Révision 957bebf1
GES_PAC/AppShell.xaml | ||
---|---|---|
10 | 10 |
Title="GES_PAC"> |
11 | 11 |
|
12 | 12 |
|
13 |
<!-- |
|
13 | 14 |
<ShellContent |
14 | 15 |
Title="Accueil" |
15 | 16 |
Route="Main" |
16 | 17 |
ContentTemplate="{DataTemplate local:MainView}" /> |
18 |
--> |
|
17 | 19 |
|
18 | 20 |
<ShellContent |
19 | 21 |
Title="Remorque" |
GES_PAC/AppShell.xaml.cs | ||
---|---|---|
23 | 23 |
Routing.RegisterRoute(nameof(CreateBehaviourView), typeof(CreateBehaviourView)); |
24 | 24 |
Routing.RegisterRoute(nameof(EndSetView), typeof(EndSetView)); |
25 | 25 |
Routing.RegisterRoute(nameof(EndDayView), typeof(EndDayView)); |
26 |
Routing.RegisterRoute(nameof(ExportDataView), typeof(ExportDataView)); |
|
26 | 27 |
} |
27 | 28 |
} |
28 | 29 |
} |
GES_PAC/GES_PAC.csproj | ||
---|---|---|
25 | 25 |
<ApplicationTitle>GES_PAC</ApplicationTitle> |
26 | 26 |
|
27 | 27 |
<!-- App Identifier --> |
28 |
<ApplicationId>fr.inrae.sicpa.GES_PAC</ApplicationId>
|
|
28 |
<ApplicationId>fr.inrae.GES_PAC</ApplicationId> |
|
29 | 29 |
|
30 | 30 |
<!-- Versions --> |
31 | 31 |
<ApplicationDisplayVersion>1.0</ApplicationDisplayVersion> |
GES_PAC/GES_PAC.csproj.user | ||
---|---|---|
3 | 3 |
<PropertyGroup> |
4 | 4 |
<IsFirstTimeProjectOpen>False</IsFirstTimeProjectOpen> |
5 | 5 |
<ActiveDebugFramework>net9.0-android</ActiveDebugFramework> |
6 |
<ActiveDebugProfile>Android Emulator</ActiveDebugProfile>
|
|
7 |
<SelectedPlatformGroup>Emulator</SelectedPlatformGroup>
|
|
6 |
<ActiveDebugProfile>Samsung SM-G556B (Android 14.0 - API 34)</ActiveDebugProfile>
|
|
7 |
<SelectedPlatformGroup>PhysicalDevice</SelectedPlatformGroup>
|
|
8 | 8 |
<DefaultDevice>pixel_7_-_api_35</DefaultDevice> |
9 | 9 |
<SelectedDevice>Xiaomi 23090RA98G</SelectedDevice> |
10 | 10 |
</PropertyGroup> |
GES_PAC/Helpers/JourneeToCSV.cs | ||
---|---|---|
1 |
using GES_PAC.Model; |
|
2 |
using System.Text; |
|
3 |
|
|
4 |
namespace GES_PAC.Helpers |
|
5 |
{ |
|
6 |
public static class JourneeToCSV |
|
7 |
{ |
|
8 |
public static string[] ConvertToCSV(Journee journee) |
|
9 |
{ |
|
10 |
var sbMesure = new StringBuilder(); |
|
11 |
sbMesure.AppendLine("Elevage;Client;Responsable;Espece;Regime;MiseAJeun;Temperature;Humidite;Pression;NumBoite;Poids;DatePesee;RFID;Time;Conc_O2;Conc_CO2;Conc_CH4"); |
|
12 |
var sbComportement = new StringBuilder(); |
|
13 |
sbComportement.AppendLine("Elevage;Client;Responsable;Espece;Regime;MiseAJeun;Temperature;Humidite;Pression;NumBoite;Poids;DatePesee;RFID;Time;Comportement;Commentaire"); |
|
14 |
var sbCalibration = new StringBuilder(); |
|
15 |
sbCalibration.AppendLine("Elevage;Client;Responsable;PhaseCalibration;Time;Conc_O2;Conc_CO2;Conc_CH4"); |
|
16 |
|
|
17 |
foreach (var serie in journee.Series) |
|
18 |
{ |
|
19 |
foreach (var serieAnimal in serie.SeriesAnimales) |
|
20 |
{ |
|
21 |
foreach (var mesure in serieAnimal.Mesures) |
|
22 |
{ |
|
23 |
sbMesure.AppendLine($"{journee.Lieu.Nom};{journee.Lieu.Client};{journee.Responsable.Nom};{journee.Lieu.Espece};{journee.Regime};{serie.MiseAJeun.ToString("yyyy-MM-dd HH:mm")};{serie.Temperature};{serie.Humidite};{serie.Pression};{serieAnimal.NumeroBoite};{serieAnimal.Poids};{serieAnimal.DatePesee.ToString("yyyy-MM-dd")};{serieAnimal.RFID};{mesure.Time.ToString("HH:mm:ss")};{mesure.Conc_O2};{mesure.Conc_CO2};{mesure.Conc_CH4}"); |
|
24 |
} |
|
25 |
foreach (var comportement in serieAnimal.Comportements) |
|
26 |
{ |
|
27 |
sbComportement.AppendLine($"{journee.Lieu.Nom};{journee.Lieu.Client};{journee.Responsable.Nom};{journee.Lieu.Espece};{journee.Regime};{serie.MiseAJeun.ToString("yyyy-MM-dd HH:mm")};{serie.Temperature};{serie.Humidite};{serie.Pression};{serieAnimal.NumeroBoite};{serieAnimal.Poids};{serieAnimal.DatePesee.ToString("yyyy-MM-dd")};{serieAnimal.RFID};{comportement.Time.ToString("HH:mm:ss")};{comportement.Type.ToString()};{comportement.Commentaire}"); |
|
28 |
} |
|
29 |
} |
|
30 |
foreach (var calibration in journee.Calibrations) |
|
31 |
{ |
|
32 |
foreach (var mesure in calibration.Mesures) |
|
33 |
{ |
|
34 |
sbCalibration.AppendLine($"{journee.Lieu.Nom};{journee.Lieu.Client};{journee.Responsable.Nom};{calibration.Phase.ToString()};{mesure.Time.ToString("HH:mm:ss")};{mesure.Conc_O2};{mesure.Conc_CO2};{mesure.Conc_CH4}"); |
|
35 |
} |
|
36 |
} |
|
37 |
} |
|
38 |
return [sbMesure.ToString(), sbComportement.ToString(), sbCalibration.ToString()]; |
|
39 |
} |
|
40 |
} |
|
41 |
} |
GES_PAC/Model/Comportement.cs | ||
---|---|---|
3 | 3 |
{ |
4 | 4 |
public class Comportement |
5 | 5 |
{ |
6 |
private DateTime date; |
|
7 |
private TypeComportement selectedType; |
|
8 |
private string description; |
|
9 |
|
|
10 |
public Comportement(DateTime date, TypeComportement selectedType, string description) |
|
11 |
{ |
|
12 |
this.date = date; |
|
13 |
this.selectedType = selectedType; |
|
14 |
this.description = description; |
|
15 |
} |
|
16 |
|
|
17 | 6 |
public long Id { get; set; } |
18 | 7 |
public DateTime Time { get; set; } |
19 |
public TypeComportement? Type { get; set; }
|
|
8 |
public TypeComportement Type { get; set; } |
|
20 | 9 |
public string? Commentaire { get; set; } |
10 |
|
|
11 |
public Comportement(DateTime Time, TypeComportement Type, string Commentaire) |
|
12 |
{ |
|
13 |
this.Time = Time; |
|
14 |
this.Type = Type ?? TypeComportement.AUTRE; |
|
15 |
this.Commentaire = Commentaire; |
|
16 |
} |
|
21 | 17 |
} |
22 | 18 |
} |
GES_PAC/Model/PhaseCalibration.cs | ||
---|---|---|
11 | 11 |
Value = value; |
12 | 12 |
} |
13 | 13 |
|
14 |
public static readonly PhaseCalibration Debut = new("Début", 1);
|
|
15 |
public static readonly PhaseCalibration Fin = new("Fin", 2);
|
|
14 |
public static readonly PhaseCalibration Debut = new("DEBUT", 1);
|
|
15 |
public static readonly PhaseCalibration Fin = new("FIN", 2);
|
|
16 | 16 |
|
17 | 17 |
public static readonly List<PhaseCalibration> All = new() { Debut, Fin }; |
18 | 18 |
|
GES_PAC/Model/TypeCalibration.cs | ||
---|---|---|
11 | 11 |
Value = value; |
12 | 12 |
} |
13 | 13 |
|
14 |
public static readonly TypeCalibration Air = new("Air", 0);
|
|
15 |
public static readonly TypeCalibration Methane = new("Methane", 1);
|
|
16 |
public static readonly TypeCalibration Melange = new("Mélange", 2);
|
|
14 |
public static readonly TypeCalibration Air = new("AIR", 0);
|
|
15 |
public static readonly TypeCalibration Methane = new("METHANE", 1);
|
|
16 |
public static readonly TypeCalibration Melange = new("MELANGE", 2);
|
|
17 | 17 |
|
18 | 18 |
public static readonly List<TypeCalibration> All = new() { Air, Methane, Melange }; |
19 | 19 |
|
GES_PAC/Platforms/Android/AndroidFileHelper.cs | ||
---|---|---|
1 |
using Android.Content; |
|
2 |
using Android.Provider; |
|
3 |
using System.Text; |
|
4 |
|
|
5 |
|
|
6 |
public static class AndroidFileHelper |
|
7 |
{ |
|
8 |
public static void SaveJsonToDownloads(string fileName, string content) |
|
9 |
{ |
|
10 |
var context = Android.App.Application.Context; |
|
11 |
|
|
12 |
ContentValues values = new ContentValues(); |
|
13 |
values.Put(MediaStore.IMediaColumns.DisplayName, fileName); |
|
14 |
values.Put(MediaStore.IMediaColumns.MimeType, "text/json"); |
|
15 |
|
|
16 |
values.Put(MediaStore.IMediaColumns.RelativePath, $"{Android.OS.Environment.DirectoryDownloads}/GES_PAC"); |
|
17 |
|
|
18 |
var uri = context.ContentResolver.Insert(MediaStore.Downloads.ExternalContentUri, values); |
|
19 |
if (uri == null) throw new IOException("Impossible de créer le fichier."); |
|
20 |
|
|
21 |
using var stream = context.ContentResolver.OpenOutputStream(uri); |
|
22 |
using var writer = new StreamWriter(stream, Encoding.UTF8); |
|
23 |
writer.Write(content); |
|
24 |
writer.Flush(); |
|
25 |
} |
|
26 |
public static void SaveCSVToDownloads(string folderName, string[] contents) |
|
27 |
{ |
|
28 |
if (contents.Length != 3) |
|
29 |
throw new ArgumentException("Le tableau de contenu doit contenir exactement 3 éléments."); |
|
30 |
|
|
31 |
var context = Android.App.Application.Context; |
|
32 |
|
|
33 |
string[] fileNames = { "mesures.csv", "comportements.csv", "calibrations.csv" }; |
|
34 |
string folderPath = $"{Android.OS.Environment.DirectoryDownloads}/GES_PAC/{folderName.Replace("/","_")}"; |
|
35 |
|
|
36 |
for (int i = 0; i < fileNames.Length; i++) |
|
37 |
{ |
|
38 |
ContentValues values = new ContentValues(); |
|
39 |
values.Put(MediaStore.IMediaColumns.DisplayName, fileNames[i]); |
|
40 |
values.Put(MediaStore.IMediaColumns.MimeType, "text/csv"); |
|
41 |
values.Put(MediaStore.IMediaColumns.RelativePath, folderPath); |
|
42 |
|
|
43 |
var uri = context.ContentResolver.Insert(MediaStore.Downloads.ExternalContentUri, values); |
|
44 |
if (uri == null) throw new IOException($"Impossible de créer le fichier {fileNames[i]}."); |
|
45 |
|
|
46 |
using var stream = context.ContentResolver.OpenOutputStream(uri); |
|
47 |
using var writer = new StreamWriter(stream, Encoding.UTF8); |
|
48 |
foreach (var line in contents[i]) |
|
49 |
{ |
|
50 |
writer.Write(line); |
|
51 |
} |
|
52 |
writer.Flush(); |
|
53 |
} |
|
54 |
} |
|
55 |
} |
|
56 |
|
GES_PAC/Platforms/Android/AndroidManifest.xml | ||
---|---|---|
1 | 1 |
<?xml version="1.0" encoding="utf-8"?> |
2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android"> |
|
3 |
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:roundIcon="@mipmap/appicon_round" android:supportsRtl="true"></application>
|
|
2 |
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="fr.inrae.GES_PAC">
|
|
3 |
<application android:allowBackup="true" android:icon="@mipmap/appicon" android:supportsRtl="true" android:label="GES_PAC"></application>
|
|
4 | 4 |
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> |
5 | 5 |
<uses-permission android:name="android.permission.INTERNET" /> |
6 |
<uses-permission android:name="android.permission.BLUETOOTH" /> |
|
7 |
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> |
|
8 |
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> |
|
6 | 9 |
</manifest> |
GES_PAC/View/ChambersView.xaml | ||
---|---|---|
48 | 48 |
</Grid.RowDefinitions> |
49 | 49 |
|
50 | 50 |
<!-- Boutons Gauche --> |
51 |
<controls:ChamberButtonView Grid.Row="5" Grid.Column="0" ChamberId="1" Timer="{Binding Timer}"/>
|
|
52 |
<controls:ChamberButtonView Grid.Row="4" Grid.Column="0" ChamberId="3" Timer="{Binding Timer}"/>
|
|
53 |
<controls:ChamberButtonView Grid.Row="3" Grid.Column="0" ChamberId="5" Timer="{Binding Timer}"/>
|
|
54 |
<controls:ChamberButtonView Grid.Row="2" Grid.Column="0" ChamberId="7" Timer="{Binding Timer}"/>
|
|
55 |
<controls:ChamberButtonView Grid.Row="1" Grid.Column="0" ChamberId="9" Timer="{Binding Timer}"/>
|
|
56 |
<controls:ChamberButtonView Grid.Row="0" Grid.Column="0" ChamberId="11" Timer="{Binding Timer}"/>
|
|
51 |
<controls:ChamberButtonView Grid.Row="5" Grid.Column="0" ChamberId="1" ParentViewModel="{Binding .}"/>
|
|
52 |
<controls:ChamberButtonView Grid.Row="4" Grid.Column="0" ChamberId="3" ParentViewModel="{Binding .}"/>
|
|
53 |
<controls:ChamberButtonView Grid.Row="3" Grid.Column="0" ChamberId="5" ParentViewModel="{Binding .}"/>
|
|
54 |
<controls:ChamberButtonView Grid.Row="2" Grid.Column="0" ChamberId="7" ParentViewModel="{Binding .}"/>
|
|
55 |
<controls:ChamberButtonView Grid.Row="1" Grid.Column="0" ChamberId="9" ParentViewModel="{Binding .}"/>
|
|
56 |
<controls:ChamberButtonView Grid.Row="0" Grid.Column="0" ChamberId="11" ParentViewModel="{Binding .}"/>
|
|
57 | 57 |
|
58 | 58 |
<!-- Boutons Droite --> |
59 |
<controls:ChamberButtonView Grid.Row="5" Grid.Column="2" ChamberId="2" Timer="{Binding Timer}"/>
|
|
60 |
<controls:ChamberButtonView Grid.Row="4" Grid.Column="2" ChamberId="4" Timer="{Binding Timer}"/>
|
|
61 |
<controls:ChamberButtonView Grid.Row="3" Grid.Column="2" ChamberId="6" Timer="{Binding Timer}"/>
|
|
62 |
<controls:ChamberButtonView Grid.Row="2" Grid.Column="2" ChamberId="8" Timer="{Binding Timer}"/>
|
|
63 |
<controls:ChamberButtonView Grid.Row="1" Grid.Column="2" ChamberId="10" Timer="{Binding Timer}"/>
|
|
64 |
<controls:ChamberButtonView Grid.Row="0" Grid.Column="2" ChamberId="12" Timer="{Binding Timer}"/>
|
|
59 |
<controls:ChamberButtonView Grid.Row="5" Grid.Column="2" ChamberId="2" ParentViewModel="{Binding .}"/>
|
|
60 |
<controls:ChamberButtonView Grid.Row="4" Grid.Column="2" ChamberId="4" ParentViewModel="{Binding .}"/>
|
|
61 |
<controls:ChamberButtonView Grid.Row="3" Grid.Column="2" ChamberId="6" ParentViewModel="{Binding .}"/>
|
|
62 |
<controls:ChamberButtonView Grid.Row="2" Grid.Column="2" ChamberId="8" ParentViewModel="{Binding .}"/>
|
|
63 |
<controls:ChamberButtonView Grid.Row="1" Grid.Column="2" ChamberId="10" ParentViewModel="{Binding .}"/>
|
|
64 |
<controls:ChamberButtonView Grid.Row="0" Grid.Column="2" ChamberId="12" ParentViewModel="{Binding .}"/>
|
|
65 | 65 |
|
66 | 66 |
<!-- Couloir central --> |
67 | 67 |
<BoxView Grid.Column="1" Grid.RowSpan="6" HeightRequest="500" WidthRequest="75" Color="Gray"/> |
GES_PAC/View/Controls/ChamberButtonView.xaml.cs | ||
---|---|---|
8 | 8 |
public static readonly BindableProperty ChamberIdProperty = |
9 | 9 |
BindableProperty.Create(nameof(ChamberId), typeof(int), typeof(ChamberButtonView), default(int), propertyChanged: OnChamberIdChanged); |
10 | 10 |
|
11 |
public static readonly BindableProperty TimerProperty =
|
|
12 |
BindableProperty.Create(nameof(Timer), typeof(TimerPublisher), typeof(ChamberButtonView), propertyChanged: OnTimerChanged);
|
|
11 |
public static readonly BindableProperty ParentViewModelProperty =
|
|
12 |
BindableProperty.Create(nameof(ParentViewModel), typeof(ChambersViewModel), typeof(ChamberButtonView), propertyChanged: OnParentChanged);
|
|
13 | 13 |
|
14 |
public TimerPublisher? Timer
|
|
14 |
public ChambersViewModel? ParentViewModel
|
|
15 | 15 |
{ |
16 |
get => (TimerPublisher?)GetValue(TimerProperty);
|
|
17 |
set => SetValue(TimerProperty, value);
|
|
16 |
get => (ChambersViewModel?)GetValue(ParentViewModelProperty);
|
|
17 |
set => SetValue(ParentViewModelProperty, value);
|
|
18 | 18 |
} |
19 | 19 |
|
20 | 20 |
public int ChamberId |
... | ... | |
31 | 31 |
{ |
32 | 32 |
base.OnBindingContextChanged(); |
33 | 33 |
|
34 |
if (BindingContext is not ChamberButtonViewModel && ChamberId != 0 && Timer != null)
|
|
34 |
if (BindingContext is not ChamberButtonViewModel && ChamberId != 0 && ParentViewModel != null)
|
|
35 | 35 |
{ |
36 |
var vm = new ChamberButtonViewModel(ChamberId, Timer);
|
|
36 |
var vm = new ChamberButtonViewModel(ChamberId, ParentViewModel);
|
|
37 | 37 |
BindingContext = vm; |
38 | 38 |
vm.UpdateProperties(); |
39 | 39 |
} |
... | ... | |
48 | 48 |
vm.UpdateChamberId(id); |
49 | 49 |
} |
50 | 50 |
} |
51 |
private static void OnTimerChanged(BindableObject bindable, object oldValue, object newValue)
|
|
51 |
private static void OnParentChanged(BindableObject bindable, object oldValue, object newValue)
|
|
52 | 52 |
{ |
53 | 53 |
if (bindable is ChamberButtonView view) |
54 | 54 |
{ |
GES_PAC/View/ExportDataView.xaml | ||
---|---|---|
1 |
<?xml version="1.0" encoding="utf-8" ?> |
|
2 |
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui" |
|
3 |
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" |
|
4 |
xmlns:vm="clr-namespace:GES_PAC.ViewModel" |
|
5 |
xmlns:tools="clr-namespace:GES_PAC.View.Tools" |
|
6 |
x:Class="GES_PAC.View.ExportDataView" |
|
7 |
x:DataType="vm:ExportDataViewModel"> |
|
8 |
|
|
9 |
<Grid> |
|
10 |
<StackLayout BackgroundColor="White" Spacing="50"> |
|
11 |
|
|
12 |
<tools:ConnectionIndicatorView /> |
|
13 |
<ScrollView> |
|
14 |
<StackLayout Spacing="100"> |
|
15 |
|
|
16 |
<Label Text="Exporter les données" |
|
17 |
FontSize="22" |
|
18 |
FontAttributes="Bold" |
|
19 |
HorizontalOptions="Center"/> |
|
20 |
|
|
21 |
<Label Text="{Binding DataFoundText}" |
|
22 |
FontSize="18" |
|
23 |
HorizontalOptions="Center"/> |
|
24 |
|
|
25 |
</StackLayout> |
|
26 |
</ScrollView> |
|
27 |
<StackLayout HorizontalOptions="Center" VerticalOptions="EndAndExpand" Spacing="75" Margin="0, 0, 0, 50"> |
|
28 |
|
|
29 |
<Button |
|
30 |
Text="Exporter en JSON" |
|
31 |
Command="{Binding ExportJSONCommand}" |
|
32 |
Style="{StaticResource btnNormal}" |
|
33 |
VerticalOptions="End" |
|
34 |
HorizontalOptions="Center" |
|
35 |
IsVisible="{Binding HasData}"/> |
|
36 |
|
|
37 |
<Button |
|
38 |
Text="Exporter en CSV" |
|
39 |
Command="{Binding ExportCSVCommand}" |
|
40 |
Style="{StaticResource btnNormal}" |
|
41 |
VerticalOptions="End" |
|
42 |
HorizontalOptions="Center" |
|
43 |
IsVisible="{Binding HasData}"/> |
|
44 |
|
|
45 |
</StackLayout> |
|
46 |
|
|
47 |
</StackLayout> |
|
48 |
<Grid Grid.RowSpan="1" IsVisible="{Binding IsBusy}"> |
|
49 |
<Border StrokeThickness="0" |
|
50 |
Background="Black" |
|
51 |
Opacity="0.5" |
|
52 |
Padding="20" |
|
53 |
WidthRequest="160" |
|
54 |
HeightRequest="160" |
|
55 |
HorizontalOptions="Center" |
|
56 |
VerticalOptions="Center" |
|
57 |
StrokeShape="RoundRectangle 20"> |
|
58 |
|
|
59 |
<VerticalStackLayout HorizontalOptions="Center" VerticalOptions="Center"> |
|
60 |
<ActivityIndicator IsRunning="True" Color="White" /> |
|
61 |
<Label Text="Chargement..." |
|
62 |
FontSize="14" |
|
63 |
TextColor="white" |
|
64 |
HorizontalOptions="Center"/> |
|
65 |
</VerticalStackLayout> |
|
66 |
</Border> |
|
67 |
</Grid> |
|
68 |
|
|
69 |
</Grid> |
|
70 |
</ContentPage> |
GES_PAC/View/ExportDataView.xaml.cs | ||
---|---|---|
1 |
using GES_PAC.ViewModel; |
|
2 |
|
|
3 |
namespace GES_PAC.View; |
|
4 |
|
|
5 |
public partial class ExportDataView |
|
6 |
{ |
|
7 |
public ExportDataView() |
|
8 |
{ |
|
9 |
InitializeComponent(); |
|
10 |
BindingContext = new ExportDataViewModel(); |
|
11 |
} |
|
12 |
} |
GES_PAC/View/MainView.xaml | ||
---|---|---|
13 | 13 |
<ScrollView> |
14 | 14 |
<StackLayout Spacing="100"> |
15 | 15 |
|
16 |
<Label Text="Bonjour" |
|
17 |
FontSize="22" |
|
18 |
FontAttributes="Bold" |
|
19 |
HorizontalOptions="Center"/> |
|
16 |
<Grid ColumnDefinitions="*,Auto,*" Padding="10"> |
|
17 |
|
|
18 |
<Button Text="Exporter" |
|
19 |
Command="{Binding ExportDataCommand}" |
|
20 |
Grid.Column="0" |
|
21 |
HorizontalOptions="Start" |
|
22 |
VerticalOptions="Center" /> |
|
23 |
|
|
24 |
<Label Text="Bonjour" |
|
25 |
Grid.Column="1" |
|
26 |
FontSize="22" |
|
27 |
FontAttributes="Bold" |
|
28 |
HorizontalOptions="Center" |
|
29 |
VerticalOptions="Center" /> |
|
30 |
|
|
31 |
</Grid> |
|
20 | 32 |
|
21 | 33 |
<Label Text="{Binding CurrentDayText}" |
22 | 34 |
FontSize="18" |
GES_PAC/ViewModel/ChambersViewModel.cs | ||
---|---|---|
19 | 19 |
|
20 | 20 |
#region Propriétés |
21 | 21 |
public TimerPublisher Timer { get; } |
22 |
public List<ChamberButtonViewModel> Buttons { get; } = new(); |
|
23 |
|
|
22 | 24 |
#endregion |
23 | 25 |
|
24 | 26 |
#region Constructeurs |
... | ... | |
45 | 47 |
internal async void OnAppearing() |
46 | 48 |
{ |
47 | 49 |
CurrentSet = JourneeViewModel.Instance.GetCurrentSet(); |
50 |
RefreshAll(); |
|
51 |
|
|
48 | 52 |
if (CurrentSet == null) |
49 | 53 |
{ |
50 | 54 |
IsBusy = true; |
... | ... | |
52 | 56 |
IsBusy = false; |
53 | 57 |
} |
54 | 58 |
} |
59 |
public void RegisterButton(ChamberButtonViewModel vm) |
|
60 |
{ |
|
61 |
if (!Buttons.Contains(vm)) |
|
62 |
Buttons.Add(vm); |
|
63 |
} |
|
64 |
public void RefreshAll() |
|
65 |
{ |
|
66 |
foreach (var btn in Buttons) |
|
67 |
btn.UpdateProperties(); |
|
68 |
} |
|
69 |
|
|
55 | 70 |
#endregion |
56 | 71 |
} |
57 | 72 |
} |
GES_PAC/ViewModel/Controls/ChamberButtonViewModel.cs | ||
---|---|---|
101 | 101 |
|
102 | 102 |
#region Constructeurs |
103 | 103 |
|
104 |
public ChamberButtonViewModel(int chamberId, TimerPublisher timerPublisher)
|
|
104 |
public ChamberButtonViewModel(int chamberId, ChambersViewModel parentViewModel)
|
|
105 | 105 |
{ |
106 | 106 |
ChamberId = chamberId; |
107 |
_timer = timerPublisher; |
|
107 |
_timer = parentViewModel.Timer; |
|
108 |
parentViewModel.RegisterButton(this); |
|
108 | 109 |
|
109 | 110 |
OnClickChamberCommand = new Command(async () => await GoToChamber()); |
110 |
ButtonBackgroundColor = Colors.White; |
|
111 |
ButtonIsEnabled = true; |
|
112 |
ButtonLabel = "0"; |
|
113 |
TimeIn = ""; |
|
111 |
InitButtonProperties(); |
|
114 | 112 |
CurrentSet = JourneeViewModel.Instance?.GetCurrentSet(); |
115 | 113 |
|
116 | 114 |
UpdateChamberId(chamberId); |
... | ... | |
124 | 122 |
ChamberId = chamberId; |
125 | 123 |
UpdateProperties(); |
126 | 124 |
} |
125 |
public void InitButtonProperties() |
|
126 |
{ |
|
127 |
ButtonBackgroundColor = Colors.White; |
|
128 |
ButtonIsEnabled = true; |
|
129 |
ButtonLabel = "0"; |
|
130 |
TimeIn = ""; |
|
131 |
} |
|
127 | 132 |
public void UpdateProperties() |
128 | 133 |
{ |
129 | 134 |
CurrentSet = JourneeViewModel.Instance?.GetCurrentSet(); |
130 | 135 |
AnimalSet = CurrentSet?.GetSerieAnimalByNumBoite(ChamberId); |
131 | 136 |
ButtonText = ChamberId.ToString(); |
137 |
InitButtonProperties(); |
|
132 | 138 |
|
133 | 139 |
int measureCount = AnimalSet?.GetMeasureCount() ?? 0; |
134 | 140 |
|
GES_PAC/ViewModel/CreateBehaviourViewModel.cs | ||
---|---|---|
89 | 89 |
IsBusy = true; |
90 | 90 |
|
91 | 91 |
var date = DateTime.Now; |
92 |
var set = JourneeViewModel.Instance.GetCurrentSet(); |
|
93 | 92 |
var newBehaviour = new Comportement(date, SelectedType, Description); |
94 |
set.AddBehaviour(newBehaviour, ChamberId, IsAnimalOut); |
|
93 |
var currentSet = JourneeViewModel.Instance.GetCurrentDay().GetCurrentSet(); |
|
94 |
currentSet.AddBehaviour(newBehaviour, ChamberId, IsAnimalOut); |
|
95 | 95 |
|
96 | 96 |
await Shell.Current.Navigation.PopToRootAsync(); |
97 | 97 |
IsBusy = false; |
GES_PAC/ViewModel/CreateCalibrationViewModel.cs | ||
---|---|---|
35 | 35 |
set |
36 | 36 |
{ |
37 | 37 |
_selectedType = value; |
38 |
IsRefBouteilleVisible = _selectedType.Name != "Air";
|
|
38 |
IsRefBouteilleVisible = _selectedType != TypeCalibration.Air;
|
|
39 | 39 |
OnPropertyChanged(); |
40 | 40 |
OnTypeChanged(); |
41 | 41 |
ValidateForm(); |
GES_PAC/ViewModel/CreateMeasureViewModel.cs | ||
---|---|---|
196 | 196 |
var date = DateTime.Now; |
197 | 197 |
var newMeasure = new Mesure(date, ConcO2 ?? 0, ConcCO2 ?? 0, ConcCH4 ?? 0); |
198 | 198 |
var currentSet = JourneeViewModel.Instance.GetCurrentDay().GetCurrentSet(); |
199 |
|
|
200 | 199 |
currentSet.AddMeasure(newMeasure, ChamberId, IsAnimalOut); |
201 | 200 |
|
202 | 201 |
await Shell.Current.Navigation.PopToRootAsync(); |
203 |
|
|
204 | 202 |
IsBusy = false; |
205 | 203 |
} |
206 | 204 |
private async Task GoToBehaviour() |
GES_PAC/ViewModel/ExportDataViewModel.cs | ||
---|---|---|
1 |
using System.Windows.Input; |
|
2 |
using GES_PAC.Model; |
|
3 |
using GES_PAC.Helpers; |
|
4 |
using System.Text.Json; |
|
5 |
using System.Collections.ObjectModel; |
|
6 |
|
|
7 |
|
|
8 |
namespace GES_PAC.ViewModel |
|
9 |
{ |
|
10 |
public class ExportDataViewModel : BaseViewModel |
|
11 |
{ |
|
12 |
#region Attributs |
|
13 |
private bool _hasData = false; |
|
14 |
public string _dataFoundText; |
|
15 |
#endregion |
|
16 |
|
|
17 |
#region Propriétés |
|
18 |
public bool HasData |
|
19 |
{ |
|
20 |
get => _hasData; |
|
21 |
set |
|
22 |
{ |
|
23 |
SetProperty(ref _hasData, value); |
|
24 |
OnPropertyChanged(); |
|
25 |
} |
|
26 |
} |
|
27 |
public string DataFoundText |
|
28 |
{ |
|
29 |
get => _dataFoundText; |
|
30 |
set |
|
31 |
{ |
|
32 |
SetProperty(ref _dataFoundText, value); |
|
33 |
OnPropertyChanged(); |
|
34 |
} |
|
35 |
} |
|
36 |
public ObservableCollection<Journee>? DayList { get; set; } |
|
37 |
#endregion |
|
38 |
|
|
39 |
#region Commandes |
|
40 |
public ICommand ExportJSONCommand { get; } |
|
41 |
public ICommand ExportCSVCommand { get; } |
|
42 |
#endregion |
|
43 |
|
|
44 |
#region Constructeur |
|
45 |
public ExportDataViewModel() |
|
46 |
{ |
|
47 |
ExportJSONCommand = new Command(ExportJSON); |
|
48 |
ExportCSVCommand = new Command(ExportCSV); |
|
49 |
|
|
50 |
DayList = JourneeViewModel.Instance?.Journees ?? null; |
|
51 |
HasData = DayList != null && DayList.Count > 0; |
|
52 |
DataFoundText = HasData ? "Données trouvées" : "Aucune donnée trouvée"; |
|
53 |
} |
|
54 |
#endregion |
|
55 |
|
|
56 |
#region Méthodes |
|
57 |
private void ExportJSON() |
|
58 |
{ |
|
59 |
#if ANDROID |
|
60 |
if(IsBusy) return; |
|
61 |
IsBusy = true; |
|
62 |
var lastDay = DayList.Last(); |
|
63 |
string fileName = lastDay.Date.ToString(); |
|
64 |
string json = JsonSerializer.Serialize(lastDay); |
|
65 |
AndroidFileHelper.SaveJsonToDownloads(fileName, json); |
|
66 |
IsBusy = false; |
|
67 |
#endif |
|
68 |
} |
|
69 |
|
|
70 |
private void ExportCSV() |
|
71 |
{ |
|
72 |
#if ANDROID |
|
73 |
if(IsBusy) return; |
|
74 |
IsBusy = true; |
|
75 |
var lastDay = DayList.Last(); |
|
76 |
string folderName = lastDay.Date.ToString(); |
|
77 |
string[] csv = JourneeToCSV.ConvertToCSV(lastDay); |
|
78 |
Console.WriteLine(csv[0]); |
|
79 |
AndroidFileHelper.SaveCSVToDownloads(folderName, csv); |
|
80 |
IsBusy = false; |
|
81 |
#endif |
|
82 |
} |
|
83 |
|
|
84 |
#endregion |
|
85 |
} |
|
86 |
} |
|
87 |
|
GES_PAC/ViewModel/MainViewModel.cs | ||
---|---|---|
12 | 12 |
private string _currentDayText; |
13 | 13 |
#endregion |
14 | 14 |
|
15 |
|
|
16 |
|
|
17 | 15 |
#region Commandes |
18 | 16 |
public ICommand GoToCreateDayCommand { get; } |
19 | 17 |
public ICommand ResumeDayCommand { get; } |
18 |
public ICommand ExportDataCommand { get; } |
|
20 | 19 |
#endregion |
21 | 20 |
|
22 | 21 |
#region Propriétés |
... | ... | |
53 | 52 |
public MainViewModel() |
54 | 53 |
{ |
55 | 54 |
//ONLY FOR TESTS |
56 |
//var date = DateTime.Now;
|
|
57 |
//var newDay = new Journee(date, PersonViewModel.Instance.Persons[0], PlaceViewModel.Instance.Places[0], "");
|
|
58 |
//newDay.AddSet(new Serie(date, date, 25, 25, 25));
|
|
59 |
//newDay.AddCalibration(new MesureCalibration(date, 50, 40, 500, TypeCalibration.Air, ""), PhaseCalibration.Debut);
|
|
60 |
//newDay.AddCalibration(new MesureCalibration(date, 0, 0, 1000000, TypeCalibration.Methane, "dazdazd"), PhaseCalibration.Debut);
|
|
61 |
//newDay.AddCalibration(new MesureCalibration(date, 30, 30, 3000, TypeCalibration.Melange, "deqsfsdf"), PhaseCalibration.Debut);
|
|
62 |
//newDay.GetCurrentSet().AddSerieAnimal(new SerieAnimal(1, 500, date, ""));
|
|
63 |
//newDay.GetCurrentSet().AddMeasure(new Mesure(date, 50, 50, 50), 1, false);
|
|
64 |
//JourneeViewModel.Instance.Journees.Add(newDay);
|
|
55 |
var date = DateTime.Now; |
|
56 |
var newDay = new Journee(date, PersonViewModel.Instance.Persons[0], PlaceViewModel.Instance.Places[0], ""); |
|
57 |
newDay.AddSet(new Serie(date, date, 25, 25, 25)); |
|
58 |
newDay.AddCalibration(new MesureCalibration(date, 50, 40, 500, TypeCalibration.Air, ""), PhaseCalibration.Debut); |
|
59 |
newDay.AddCalibration(new MesureCalibration(date, 0, 0, 1000000, TypeCalibration.Methane, "dazdazd"), PhaseCalibration.Debut); |
|
60 |
newDay.AddCalibration(new MesureCalibration(date, 30, 30, 3000, TypeCalibration.Melange, "deqsfsdf"), PhaseCalibration.Debut); |
|
61 |
newDay.GetCurrentSet().AddSerieAnimal(new SerieAnimal(1, 500, date, "")); |
|
62 |
newDay.GetCurrentSet().AddMeasure(new Mesure(date, 50, 50, 50), 1, false); |
|
63 |
JourneeViewModel.Instance.Journees.Add(newDay); |
|
65 | 64 |
//ONLY FOR TESTS |
66 | 65 |
|
67 | 66 |
GoToCreateDayCommand = new Command(async () => await GoToCreateDayPage()); |
68 | 67 |
ResumeDayCommand = new Command(async () => await ResumeDay()); |
68 |
ExportDataCommand = new Command(async () => await ExportData()); |
|
69 | 69 |
|
70 | 70 |
GetLastDay(); |
71 | 71 |
} |
... | ... | |
100 | 100 |
|
101 | 101 |
await Shell.Current.GoToAsync(targetView); |
102 | 102 |
IsBusy = false; |
103 |
} |
|
104 |
private async Task ExportData() |
|
105 |
{ |
|
106 |
if (IsBusy) return; |
|
107 |
IsBusy = true; |
|
108 |
await Shell.Current.GoToAsync(nameof(ExportDataView)); |
|
109 |
IsBusy = false; |
|
103 | 110 |
} |
104 | 111 |
#endregion |
105 | 112 |
} |
Formats disponibles : Unified diff