ntminer vor 4 Jahren
Ursprung
Commit
2234c7f348

+ 7 - 7
docs/WebSite/index.html

@@ -29,7 +29,7 @@
                 <div>
                     <div class="col-6 col-xl-12 col-md-8 col-sm-8 header-icon navbar-collapse navbar-brand"></div>
                     <div class="download col-sm-12 col-6">
-                        <a href="https://zhuanlan.zhihu.com/p/360330252" target="_blank">下载地址</a>
+                        <a href="https://ntminer.coding.net/s/7eb98771-054c-485d-862a-3bbeea629a43/1" target="_blank">下载地址</a>
                         <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#collapsibleNavbar">
                             <span class="navbar-toggler-icon"></span>
                         </button>
@@ -53,7 +53,7 @@
                             <a class="nav-link" href="https://github.com/ntminer/NtMiner" target="_blank">源码</a>
                         </li>
                         <li class="nav-item  align-items-center big-screen-down">
-                            <a class="nav-link" href="https://zhuanlan.zhihu.com/p/360330252" target="_blank">下载地址</a>
+                            <a class="nav-link" href="https://ntminer.coding.net/s/7eb98771-054c-485d-862a-3bbeea629a43/1" target="_blank">下载地址</a>
                         </li>
                     </ul>
                 </div>
@@ -67,7 +67,7 @@
 					<p class="title-p">开源矿工永远开源;</p>
 					<p class="title-p">开源矿工永不破解国人开发的内核;</p>
                     <div class="row banner-btn-content">
-                        <a href="https://zhuanlan.zhihu.com/p/360330252" target="_blank" class="btn col-xl-3 col-md-4 col-sm-4 col-5"> <img src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/Windows.png" alt="download button icon"> 下载地址</a>
+                        <a href="https://ntminer.coding.net/s/7eb98771-054c-485d-862a-3bbeea629a43/1" target="_blank" class="btn col-xl-3 col-md-4 col-sm-4 col-5"> <img src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/Windows.png" alt="download button icon"> 下载地址</a>
                     </div>
 					<a href="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/index-pic.png?1" target="_blank"><img class="banner-pic col-xl-10 col-md-10 col-sm-12 col-12" src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/index-pic.png?20200501" alt="index"></a>
                 </div>
@@ -206,8 +206,8 @@
             </section>
 
             <div class="wechat">
-                <a href="https://jq.qq.com/?_wv=1027&k=k3hXnSsS" target="_blank">
-                    <img src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20210518" alt="wechat">
+                <a href="https://jq.qq.com/?_wv=1027&k=rHE4P02o" target="_blank">
+                    <img src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20210928" style="width:280px;" alt="QQ群">
                 </a>
             </div>
         </div>
@@ -223,7 +223,7 @@
                     </div>
                     <div class="col-sm-3 col-md-2 col-xl-2 footer-item ">
                         <h6>下载</h6>
-                        <p><a href="https://zhuanlan.zhihu.com/p/360330252" target="_blank">下载地址</a></p>
+                        <p><a href="https://ntminer.coding.net/s/7eb98771-054c-485d-862a-3bbeea629a43/1" target="_blank">下载地址</a></p>
                         <p><a href="https://github.com/ntminer/NtMiner" target="_blank">源代码</a></p>
                     </div>
                     <div class="col-sm-3 footer-item col-md-2">
@@ -232,7 +232,7 @@
                     </div>
                     <div class="col-sm-4 footer-item col-xl-3  col-md-4">
                         <h6>联系方式</h6>
-                        <img data-toggle="tooltip" data-placement="top" title="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgdmlld0JveD0iMCAwIDMwIDMwIj4KICAgIDxwYXRoIGZpbGw9IiM3NzciIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQuNzU2IDE2Ljg1NWMtLjg2OSAyLjExMy0xLjAxIDQuMTI4LS4zMTMgNC41MDUuNDgxLjI2IDEuMjM1LS4zMyAxLjk0LTEuNDE1LjI4IDEuMTgxLjk3IDIuMjUgMS45NTggMy4xMDgtMS4wMzUuMzk1LTEuNzEyIDEuMDQtMS43MTIgMS43NzIgMCAxLjIwMiAxLjgzIDIuMTc1IDQuMDkgMi4xNzUgMi4wMzggMCAzLjcyNi0uNzkgNC4wMzctMS44M2guNDg2Yy4zMTMgMS4wNCAyLjAwMyAxLjgzIDQuMDM5IDEuODMgMi4yNiAwIDQuMDktLjk3NCA0LjA5LTIuMTc1IDAtLjczLS42NzYtMS4zNzctMS43MTMtMS43NzIuOTg3LS44NTggMS42OC0xLjkyNyAxLjk1OS0zLjEwOC43MDUgMS4wODQgMS40NTcgMS42NzUgMS45MzggMS40MTUuNjk4LS4zNzcuNTYtMi4zOTMtLjMxMS00LjUwNS0uNjgyLTEuNjYtMS42MDgtMi44ODItMi4zMTYtMy4xNTIuMDEtLjEwNS4wMTUtLjIxMi4wMTUtLjMyIDAtLjY0LS4xNzItMS4yMzMtLjQ2Ny0xLjcxNi4wMDUtLjAzOC4wMDUtLjA3Ni4wMDUtLjExNGExLjg2IDEuODYgMCAwIDAtLjE4NC0uODFDMjIuMTIgNi40MjYgMTkuNCAzIDE1IDNjLTQuNDAyIDAtNy4xMjIgMy40MjctNy4zIDcuNzQyYTEuODUzIDEuODUzIDAgMCAwLS4xODQuODExYzAgLjAzOC4wMDMuMDc2LjAwNC4xMTRhMy4zMTkgMy4zMTkgMCAwIDAtLjQ2NSAxLjcxN2MwIC4xMDcuMDA0LjIxMy4wMTMuMzItLjcwMy4yNjktMS42MzIgMS40OTQtMi4zMTIgMy4xNTF6Ii8+Cjwvc3ZnPgo=" data-html="true" alt="QQ icon" data-original-title="&lt;img src=&#39;https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20210414&#39; width=&#39;190px&#39;&gt; ">
+                        <img data-toggle="tooltip" data-placement="top" title="" src="data:image/svg+xml;base64,PHN2ZyB4bWxucz0iaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmciIHdpZHRoPSIzMCIgaGVpZ2h0PSIzMCIgdmlld0JveD0iMCAwIDMwIDMwIj4KICAgIDxwYXRoIGZpbGw9IiM3NzciIGZpbGwtcnVsZT0iZXZlbm9kZCIgZD0iTTQuNzU2IDE2Ljg1NWMtLjg2OSAyLjExMy0xLjAxIDQuMTI4LS4zMTMgNC41MDUuNDgxLjI2IDEuMjM1LS4zMyAxLjk0LTEuNDE1LjI4IDEuMTgxLjk3IDIuMjUgMS45NTggMy4xMDgtMS4wMzUuMzk1LTEuNzEyIDEuMDQtMS43MTIgMS43NzIgMCAxLjIwMiAxLjgzIDIuMTc1IDQuMDkgMi4xNzUgMi4wMzggMCAzLjcyNi0uNzkgNC4wMzctMS44M2guNDg2Yy4zMTMgMS4wNCAyLjAwMyAxLjgzIDQuMDM5IDEuODMgMi4yNiAwIDQuMDktLjk3NCA0LjA5LTIuMTc1IDAtLjczLS42NzYtMS4zNzctMS43MTMtMS43NzIuOTg3LS44NTggMS42OC0xLjkyNyAxLjk1OS0zLjEwOC43MDUgMS4wODQgMS40NTcgMS42NzUgMS45MzggMS40MTUuNjk4LS4zNzcuNTYtMi4zOTMtLjMxMS00LjUwNS0uNjgyLTEuNjYtMS42MDgtMi44ODItMi4zMTYtMy4xNTIuMDEtLjEwNS4wMTUtLjIxMi4wMTUtLjMyIDAtLjY0LS4xNzItMS4yMzMtLjQ2Ny0xLjcxNi4wMDUtLjAzOC4wMDUtLjA3Ni4wMDUtLjExNGExLjg2IDEuODYgMCAwIDAtLjE4NC0uODFDMjIuMTIgNi40MjYgMTkuNCAzIDE1IDNjLTQuNDAyIDAtNy4xMjIgMy40MjctNy4zIDcuNzQyYTEuODUzIDEuODUzIDAgMCAwLS4xODQuODExYzAgLjAzOC4wMDMuMDc2LjAwNC4xMTRhMy4zMTkgMy4zMTkgMCAwIDAtLjQ2NSAxLjcxN2MwIC4xMDcuMDA0LjIxMy4wMTMuMzItLjcwMy4yNjktMS42MzIgMS40OTQtMi4zMTIgMy4xNTF6Ii8+Cjwvc3ZnPgo=" data-html="true" alt="QQ icon" data-original-title="&lt;img src=&#39;https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/NTMiner_QQGroupQrCode.png#20210928&#39; width=&#39;190px&#39;&gt; ">
                         <img style="margin-left:8px" data-toggle="tooltip" data-placement="top" title="" src="https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/footer-icon-wechat.svg?v=01692ab" data-html="true" alt="WeChat icon" data-original-title="&lt;img src=&#39;https://ntwebsite.oss-cn-beijing.aliyuncs.com/img/wechat-pic.jpg&#39; width=&#39;190px&#39;&gt;">
                     </div>
                 </div>

+ 5 - 0
src/AppModels/AppStatic.cs

@@ -740,6 +740,11 @@ namespace NTMiner {
             Process.Start(url);
         });
 
+        public static ICommand OpenDualMineDescription { get; private set; } = new DelegateCommand(() => {
+            string url = "https://zhuanlan.zhihu.com/p/346734794";
+            Process.Start(url);
+        });
+
         public static string QQGroup {
             get {
                 if (WpfUtil.IsInDesignMode) {

+ 66 - 0
src/AppModels/Vms/MinerProfileViewModel.cs

@@ -988,6 +988,72 @@ namespace NTMiner.Vms {
             }
         }
 
+        public bool IsAutoStopByGpu {
+            get => NTMinerContext.Instance.MinerProfile.IsAutoStopByGpu;
+            set {
+                if (NTMinerContext.Instance.MinerProfile.IsAutoStopByGpu != value) {
+                    NTMinerContext.Instance.GpuTemperatureReset();
+                    NTMinerContext.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsAutoStopByGpu), value);
+                    OnPropertyChanged(nameof(IsAutoStopByGpu));
+                }
+            }
+        }
+
+        public int GpuStopTemperature {
+            get => NTMinerContext.Instance.MinerProfile.GpuStopTemperature;
+            set {
+                if (NTMinerContext.Instance.MinerProfile.GpuStopTemperature != value) {
+                    NTMinerContext.Instance.GpuTemperatureReset();
+                    NTMinerContext.Instance.MinerProfile.SetMinerProfileProperty(nameof(GpuStopTemperature), value);
+                    OnPropertyChanged(nameof(GpuStopTemperature));
+                }
+            }
+        }
+
+        public int GpuGETemperatureSeconds {
+            get => NTMinerContext.Instance.MinerProfile.GpuGETemperatureSeconds;
+            set {
+                if (NTMinerContext.Instance.MinerProfile.GpuGETemperatureSeconds != value) {
+                    NTMinerContext.Instance.GpuTemperatureReset();
+                    NTMinerContext.Instance.MinerProfile.SetMinerProfileProperty(nameof(GpuGETemperatureSeconds), value);
+                    OnPropertyChanged(nameof(GpuGETemperatureSeconds));
+                }
+            }
+        }
+
+        public bool IsAutoStartByGpu {
+            get => NTMinerContext.Instance.MinerProfile.IsAutoStartByGpu;
+            set {
+                if (NTMinerContext.Instance.MinerProfile.IsAutoStartByGpu != value) {
+                    NTMinerContext.Instance.GpuTemperatureReset();
+                    NTMinerContext.Instance.MinerProfile.SetMinerProfileProperty(nameof(IsAutoStartByGpu), value);
+                    OnPropertyChanged(nameof(IsAutoStartByGpu));
+                }
+            }
+        }
+
+        public int GpuStartTemperature {
+            get => NTMinerContext.Instance.MinerProfile.GpuStartTemperature;
+            set {
+                if (NTMinerContext.Instance.MinerProfile.GpuStartTemperature != value) {
+                    NTMinerContext.Instance.GpuTemperatureReset();
+                    NTMinerContext.Instance.MinerProfile.SetMinerProfileProperty(nameof(GpuStartTemperature), value);
+                    OnPropertyChanged(nameof(GpuStartTemperature));
+                }
+            }
+        }
+
+        public int GpuLETemperatureSeconds {
+            get => NTMinerContext.Instance.MinerProfile.GpuLETemperatureSeconds;
+            set {
+                if (NTMinerContext.Instance.MinerProfile.GpuLETemperatureSeconds != value) {
+                    NTMinerContext.Instance.GpuTemperatureReset();
+                    NTMinerContext.Instance.MinerProfile.SetMinerProfileProperty(nameof(GpuLETemperatureSeconds), value);
+                    OnPropertyChanged(nameof(GpuLETemperatureSeconds));
+                }
+            }
+        }
+
         public bool IsRaiseHighCpuEvent {
             get => NTMinerContext.Instance.MinerProfile.IsRaiseHighCpuEvent;
             set {

+ 24 - 0
src/AppModels/Vms/SysDicPageViewModel.cs

@@ -1,11 +1,25 @@
 using System.Linq;
+using System.Windows.Input;
 
 namespace NTMiner.Vms {
     public class SysDicPageViewModel : ViewModelBase {
+        public ICommand ClearAlgo { get; private set; }
+
         public SysDicPageViewModel() {
             if (WpfUtil.IsInDesignMode) {
                 return;
             }
+            this.ClearAlgo = new DelegateCommand(() => {
+                this.ShowSoftDialog(new DialogWindowViewModel(message: $"确定清理未使用的算法字典项吗?", title: "确认", onYes: () => {
+                    var items = NTMinerContext.Instance.ServerContext.SysDicItemSet.GetSysDicItems("Algo");
+                    if (items != null) {
+                        var toClearItemIds = items.Where(a => NTMinerContext.Instance.ServerContext.CoinSet.AsEnumerable().All(c => c.AlgoId != a.GetId())).Select(a => a.GetId()).ToArray();
+                        foreach (var id in toClearItemIds) {
+                            VirtualRoot.Execute(new RemoveSysDicItemCommand(id));
+                        }
+                    }
+                }));
+            });
             this._currentSysDic = SysDicVms.List.FirstOrDefault();
         }
 
@@ -16,7 +30,17 @@ namespace NTMiner.Vms {
                 if (_currentSysDic != value) {
                     _currentSysDic = value;
                     OnPropertyChanged(nameof(CurrentSysDic));
+                    OnPropertyChanged(nameof(IsAlgoDic));
+                }
+            }
+        }
+
+        public bool IsAlgoDic {
+            get {
+                if (CurrentSysDic == null) {
+                    return false;
                 }
+                return CurrentSysDic.Code == "Algo";
             }
         }
 

+ 8 - 2
src/AppViews0/Views/Ucs/CoinPage.xaml

@@ -684,8 +684,14 @@
 							</DataGridTemplateColumn>
 							<DataGridTemplateColumn IsReadOnly="True">
 								<DataGridTemplateColumn.Header>
-									<TextBlock Text="双挖币组"></TextBlock>
-								</DataGridTemplateColumn.Header>
+                                    <controls:KbLinkButton
+										Command="{x:Static app:AppStatic.OpenDualMineDescription}"
+										KbDisplayLine="False"
+										HorizontalAlignment="Left"
+										Background="Transparent">
+                                        <TextBlock Text="关于双挖"></TextBlock>
+                                    </controls:KbLinkButton>
+                                </DataGridTemplateColumn.Header>
 								<DataGridTemplateColumn.CellTemplate>
 									<DataTemplate>
                                         <TextBlock Text="{Binding SelectedDualCoinGroup.Name}"></TextBlock>

+ 2 - 2
src/AppViews0/Views/Ucs/MinerProfileDual.xaml

@@ -92,7 +92,7 @@
 						</ContextMenu>
 					</controls:KbButton.ContextMenu>
 					<WrapPanel>
-						<TextBlock Width="121" Padding="0 0 10 0" Foreground="Black" Text="{Binding CoinVm.CoinKernel.CoinKernelProfile.SelectedDualCoin.CoinProfile.DualCoinPool.Name}"></TextBlock>
+						<TextBlock Width="120" Padding="0 0 10 0" Foreground="Black" Text="{Binding CoinVm.CoinKernel.CoinKernelProfile.SelectedDualCoin.CoinProfile.DualCoinPool.Name}"></TextBlock>
 						<Path
 							Margin="0 2 0 0"
 							Width="12"
@@ -121,7 +121,7 @@
 					<WrapPanel>
 						<controls:KbButton 
 							x:Name="ButtonDualCoinWallet"
-							Width="284"
+							Width="283"
 							Padding="4"
 							BorderThickness="1"
 							BorderBrush="{StaticResource LightLineColor}"

+ 3 - 3
src/AppViews0/Views/Ucs/MinerProfileIndex.xaml

@@ -90,7 +90,7 @@
 						</ContextMenu>
 					</controls:KbButton.ContextMenu>
 					<WrapPanel>
-						<TextBlock Width="121" Padding="0 0 10 0" Foreground="Black" Text="{Binding MinerProfile.CoinVm.CoinKernel.Kernel.FullName}"></TextBlock>
+						<TextBlock Width="120" Padding="0 0 10 0" Foreground="Black" Text="{Binding MinerProfile.CoinVm.CoinKernel.Kernel.FullName}"></TextBlock>
 						<Path
 							Margin="0 2 0 0"
 							Width="12"
@@ -336,7 +336,7 @@
 				<WrapPanel>
 					<controls:KbButton 
 						x:Name="ButtonMainCoinWallet"
-						Width="284"
+						Width="283"
 						Padding="4"
                         ToolTip="请注意一定要填自己的钱包地址,不填也能挖是因为不填时会自动使用默认的测试钱包地址,这是为了方便大家测试。"
 						BorderThickness="1"
@@ -494,7 +494,7 @@
                 Padding="2 0"
 				Text="高级参数" />
 			<TextBox 
-				Width="284"
+				Width="283"
                 Height="30"
 				VerticalContentAlignment="Center"
                 ToolTip="这是高级用户的工具,通常我们无需关心这一块。"

+ 80 - 1
src/AppViews0/Views/Ucs/MinerProfileOption.xaml

@@ -12,7 +12,7 @@
 	xmlns:vm="clr-namespace:NTMiner.Vms;assembly=AppModels"
     Background="White"
     d:DataContext="{d:DesignData Source=../Design/MinerProfileViewModel.xaml}"
-	mc:Ignorable="d" d:DesignHeight="930" d:DesignWidth="600">
+	mc:Ignorable="d" d:DesignHeight="1000" d:DesignWidth="600">
     <UserControl.Resources>
         <ResourceDictionary>
             <StreamGeometry x:Key="Icon_Up">M4,0 L0,4 L8,4 z</StreamGeometry>
@@ -635,6 +635,85 @@
                                 </WrapPanel>
                             </CheckBox>
                         </WrapPanel>
+                        <WrapPanel Margin="{StaticResource RowThickness}">
+                            <CheckBox
+								FocusVisualStyle="{x:Null}"
+								Padding="0"
+								VerticalContentAlignment="Center"
+								IsChecked="{Binding IsAutoStopByGpu}">
+                                <WrapPanel>
+                                    <TextBlock VerticalAlignment="Center">GPU 温度持续</TextBlock>
+                                    <TextBox Style="{StaticResource TbUpDown}" Text="{Binding GpuGETemperatureSeconds}" HorizontalAlignment="Left"></TextBox>
+                                    <StackPanel Margin="0 0 2 0">
+                                        <Button Height="12" Command="{Binding Up}" CommandParameter="GpuGETemperatureSeconds">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Up}"/>
+                                            </Button.Content>
+                                        </Button>
+                                        <Button Height="12" Command="{Binding Down}" CommandParameter="GpuGETemperatureSeconds">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Down}"/>
+                                            </Button.Content>
+                                        </Button>
+                                    </StackPanel>
+                                    <TextBlock VerticalAlignment="Center">秒不低于</TextBlock>
+                                    <TextBox Style="{StaticResource TbUpDown}" Text="{Binding GpuStopTemperature,ValidatesOnExceptions=True}" HorizontalAlignment="Left"></TextBox>
+                                    <StackPanel Margin="0 0 2 0">
+                                        <Button Height="12" Command="{Binding Up}" CommandParameter="GpuStopTemperature">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Up}"/>
+                                            </Button.Content>
+                                        </Button>
+                                        <Button Height="12" Command="{Binding Down}" CommandParameter="GpuStopTemperature">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Down}"/>
+                                            </Button.Content>
+                                        </Button>
+                                    </StackPanel>
+                                    <TextBlock VerticalAlignment="Center">℃ 停止挖矿</TextBlock>
+                                </WrapPanel>
+                            </CheckBox>
+                        </WrapPanel>
+                        <WrapPanel Margin="{StaticResource RowThickness}">
+                            <CheckBox
+								FocusVisualStyle="{x:Null}"
+								Padding="0"
+                                IsEnabled="{Binding IsAutoStopByGpu}"
+								VerticalContentAlignment="Center"
+								IsChecked="{Binding IsAutoStartByGpu}">
+                                <WrapPanel>
+                                    <TextBlock VerticalAlignment="Center">GPU 温度持续</TextBlock>
+                                    <TextBox Style="{StaticResource TbUpDown}" Text="{Binding GpuLETemperatureSeconds}" HorizontalAlignment="Left"></TextBox>
+                                    <StackPanel Margin="0 0 2 0">
+                                        <Button Height="12" Command="{Binding Up}" CommandParameter="GpuLETemperatureSeconds">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Up}"/>
+                                            </Button.Content>
+                                        </Button>
+                                        <Button Height="12" Command="{Binding Down}" CommandParameter="GpuLETemperatureSeconds">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Down}"/>
+                                            </Button.Content>
+                                        </Button>
+                                    </StackPanel>
+                                    <TextBlock VerticalAlignment="Center">秒不高于</TextBlock>
+                                    <TextBox Style="{StaticResource TbUpDown}" Text="{Binding GpuStartTemperature,ValidatesOnExceptions=True}" HorizontalAlignment="Left"></TextBox>
+                                    <StackPanel Margin="0 0 2 0">
+                                        <Button Height="12" Command="{Binding Up}" CommandParameter="GpuStartTemperature">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Up}"/>
+                                            </Button.Content>
+                                        </Button>
+                                        <Button Height="12" Command="{Binding Down}" CommandParameter="GpuStartTemperature">
+                                            <Button.Content>
+                                                <Path HorizontalAlignment="Center" VerticalAlignment="Center" Fill="Black" Data="{StaticResource Icon_Down}"/>
+                                            </Button.Content>
+                                        </Button>
+                                    </StackPanel>
+                                    <TextBlock VerticalAlignment="Center">℃ 开始挖矿</TextBlock>
+                                </WrapPanel>
+                            </CheckBox>
+                        </WrapPanel>
                     </StackPanel>
                 </GroupBox>
                 <Border

+ 18 - 3
src/AppViews0/Views/Ucs/SysDicPage.xaml

@@ -255,7 +255,7 @@
                 Visibility="{x:Static app:AppStatic.IsDevModeVisible}"
                 Command="{Binding CurrentSysDic.AddSysDicItem}" 
                 Background="Transparent" BorderThickness="0"
-                Margin="10 0"
+                Margin="4 0"
                 CornerRadius="2" ToolTip="添加">
                 <WrapPanel>
                     <Path
@@ -267,7 +267,7 @@
                 </WrapPanel>
             </controls:KbButton>
             <controls:KbButton 
-				Margin="2 0"
+				Margin="4 0 2 0"
                 Visibility="{x:Static app:AppStatic.IsDevModeVisible}"
 				Command="{Binding CurrentSysDicItem.SortDown}" ToolTip="下移" 
 				Background="Transparent" BorderThickness="0"
@@ -282,7 +282,7 @@
                 </WrapPanel>
             </controls:KbButton>
             <controls:KbButton 
-				Margin="2 0"
+				Margin="2 0 4 0"
                 Visibility="{x:Static app:AppStatic.IsDevModeVisible}"
 				Command="{Binding CurrentSysDicItem.SortUp}" ToolTip="上移" 
 				Background="Transparent" BorderThickness="0"
@@ -296,6 +296,21 @@
 						Stretch="Fill" />
                 </WrapPanel>
             </controls:KbButton>
+            <controls:KbButton 
+				Margin="4 0"
+                Visibility="{Binding IsAlgoDic,Converter={StaticResource BoolToVisibilityConverter}}"
+				Command="{Binding ClearAlgo}" ToolTip="清理" 
+				Background="Transparent" BorderThickness="0"
+				CornerRadius="2">
+                <WrapPanel>
+                    <Path
+						Width="15"
+						Height="18"
+						Data="{StaticResource Icon_Clear}"
+						Fill="{StaticResource BtnBackground}"
+						Stretch="Fill" />
+                </WrapPanel>
+            </controls:KbButton>
         </WrapPanel>
         <TextBlock Grid.Column="2" Foreground="Red" HorizontalAlignment="Center" VerticalAlignment="Center" Visibility="{Binding CurrentSysDic.SysDicItems, Converter={StaticResource NoRecordVisibilityConverter}}">没有记录</TextBlock>
     </Grid>

+ 8 - 6
src/NTMinerClient/Core/Impl/LocalMessageSet.cs

@@ -94,12 +94,14 @@ namespace NTMiner.Core.Impl {
             try {
                 using (LiteDatabase db = new LiteDatabase(ConnString)) {
                     var col = db.GetCollection<LocalMessageData>();
-                    foreach (var item in col.FindAll().OrderBy(a => a.Timestamp)) {
-                        if (_records.Count < NTKeyword.LocalMessageSetCapacity) {
-                            _records.AddFirst(item);
-                        }
-                        else {
-                            col.Delete(item.Id);
+                    if (col.Count() > 0) {
+                        foreach (var item in col.FindAll().OrderBy(a => a.Timestamp)) {
+                            if (_records.Count < NTKeyword.LocalMessageSetCapacity) {
+                                _records.AddFirst(item);
+                            }
+                            else {
+                                col.Delete(item.Id);
+                            }
                         }
                     }
                 }

+ 5 - 1
src/NTMinerClient/Core/Impl/SysDicItemSet.cs

@@ -89,7 +89,11 @@ namespace NTMiner.Core.Impl {
                             break;
                         case NTKeyword.AlgoSysDicCode:
                             if (NTMinerContext.Instance.ServerContext.PackageSet.AsEnumerable().Any(a => a.AlgoIds.Contains(message.EntityId))) {
-                                VirtualRoot.Out.ShowWarn("该算法字典项关联有内核不能删除,请先解除关联");
+                                string s = "该";
+                                if (NTMinerContext.Instance.ServerContext.SysDicItemSet.TryGetDicItem(message.EntityId, out ISysDicItem item)) {
+                                    s = item.Code;
+                                }
+                                VirtualRoot.Out.ShowWarn($"{s}算法字典项关联有内核不能删除,请先解除关联");
                                 return;
                             }
                             break;

+ 42 - 0
src/NTMinerClient/Core/Profiles/MinerProfile.cs

@@ -558,6 +558,48 @@ namespace NTMiner.Core.Profiles {
             }
         }
 
+        public bool IsAutoStopByGpu {
+            get => _data.IsAutoStopByGpu;
+            private set {
+                _data.IsAutoStopByGpu = value;
+            }
+        }
+
+        public int GpuStopTemperature {
+            get => _data.GpuStopTemperature;
+            private set {
+                _data.GpuStopTemperature = value;
+            }
+        }
+
+        public int GpuGETemperatureSeconds {
+            get => _data.GpuGETemperatureSeconds;
+            private set {
+                _data.GpuGETemperatureSeconds = value;
+            }
+        }
+
+        public bool IsAutoStartByGpu {
+            get => _data.IsAutoStartByGpu;
+            private set {
+                _data.IsAutoStartByGpu = value;
+            }
+        }
+
+        public int GpuStartTemperature {
+            get => _data.GpuStartTemperature;
+            private set {
+                _data.GpuStartTemperature = value;
+            }
+        }
+
+        public int GpuLETemperatureSeconds {
+            get => _data.GpuLETemperatureSeconds;
+            private set {
+                _data.GpuLETemperatureSeconds = value;
+            }
+        }
+
         public bool IsRaiseHighCpuEvent {
             get => _data.IsRaiseHighCpuEvent;
             private set {

+ 4 - 0
src/NTMinerClient/Gpus/EmptyGpuSet.cs

@@ -51,6 +51,10 @@ namespace NTMiner.Gpus {
             }
         }
 
+        public DateTime HighTemperatureOn { get; set; }
+
+        public DateTime LowTemperatureOn { get; set; }
+
         public void LoadGpuState() {
             // nothing need todo
         }

+ 3 - 0
src/NTMinerClient/Gpus/IGpuSet.cs

@@ -13,6 +13,9 @@ namespace NTMiner.Gpus {
         IOverClock OverClock { get; }
         int Count { get; }
 
+
+        DateTime HighTemperatureOn { get; set; }
+        DateTime LowTemperatureOn { get; set; }
         bool TryGetGpu(int index, out IGpu gpu);
 
         List<GpuSetProperty> Properties { get; }

+ 4 - 0
src/NTMinerClient/Gpus/Impl/AMDGpuSet.cs

@@ -140,6 +140,10 @@ namespace NTMiner.Gpus.Impl {
 
         public IOverClock OverClock { get; private set; }
 
+        public DateTime HighTemperatureOn { get; set; }
+
+        public DateTime LowTemperatureOn { get; set; }
+
         public IEnumerable<IGpu> AsEnumerable() {
             return _gpus.Values;
         }

+ 4 - 0
src/NTMinerClient/Gpus/Impl/NVIDIAGpuSet.cs

@@ -123,6 +123,10 @@ namespace NTMiner.Gpus.Impl {
 
         public IOverClock OverClock { get; private set; }
 
+        public DateTime HighTemperatureOn { get; set; }
+
+        public DateTime LowTemperatureOn { get; set; }
+
         public IEnumerable<IGpu> AsEnumerable() {
             return _gpus.Values;
         }

+ 1 - 0
src/NTMinerClient/INTMinerContext.cs

@@ -51,6 +51,7 @@ namespace NTMiner {
         string GpuSetInfo { get; }
 
         IGpuSet GpuSet { get; }
+        void GpuTemperatureReset();
         IOverClockDataSet OverClockDataSet { get; }
 
         ICpuPackage CpuPackage { get; }

+ 70 - 0
src/NTMinerClient/NTMinerContext.cs

@@ -774,12 +774,82 @@ namespace NTMiner {
                             if (_gpuSet == null || (_gpuSet != EmptyGpuSet.Instance && _gpuSet.Count == 0)) {
                                 _gpuSet = EmptyGpuSet.Instance;
                             }
+                            GpuTemperatureInit();
                         }
                     }
                 }
                 return _gpuSet;
             }
         }
+
+        private void GpuTemperatureInit() {
+            if (GpuSet.Count == 0) {
+                return;
+            }
+            VirtualRoot.BuildEventPath<Per2SecondEvent>("周期更新GpuSet的状态", LogEnum.None, location: this.GetType(), PathPriority.Normal,
+                path: message => {
+                    if (GpuSet.Count == 0) {
+                        return;
+                    }
+                    #region GPU温度过高时自动停止挖矿和温度降低时自动开始挖矿
+                    if (_minerProfile.IsAutoStopByGpu) {
+                        if (IsMining) {
+                            /* 挖矿中时周期更新最后一次温度低于挖矿停止温度的时刻,然后检查最后一次低于
+                             * 挖矿停止温度的时刻距离现在是否已经超过了设定的时常,如果超过了则自动停止挖矿*/
+                            this.GpuSet.HighTemperatureOn = message.BornOn;
+                            // 如果当前温度低于挖矿停止温度则更新记录的低温时刻
+                            var maxGpu = GetMaxTemperatureGpu();
+                            if (maxGpu.Temperature < _minerProfile.GpuStopTemperature) {
+                                this.GpuSet.LowTemperatureOn = message.BornOn;
+                            }
+                            if ((message.BornOn - this.GpuSet.LowTemperatureOn).TotalSeconds >= _minerProfile.GpuGETemperatureSeconds) {
+                                this.GpuSet.LowTemperatureOn = message.BornOn;
+                                VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"自动停止挖矿,因为 GPU{maxGpu.Index} 温度连续{_minerProfile.GpuGETemperatureSeconds.ToString()}秒不低于{_minerProfile.GpuStopTemperature.ToString()}℃", toConsole: true);
+                                StopMineAsync(StopMineReason.HighGpuTemperature);
+                            }
+                        }
+                        else {
+                            /* 高温停止挖矿后周期更新最后一次温度高于挖矿停止温度的时刻,然后检查最后一次高于
+                             * 挖矿停止温度的时刻距离现在是否已经超过了设定的时常,如果超过了则自动开始挖矿*/
+                            this.GpuSet.LowTemperatureOn = message.BornOn;
+                            if (_minerProfile.IsAutoStartByGpu && StopReason == StopMineReason.HighGpuTemperature) {
+                                // 当前温度高于挖矿停止温度则更新记录的高温时刻
+                                var maxGpu = GetMaxTemperatureGpu();
+                                if (maxGpu.Temperature > _minerProfile.GpuStartTemperature) {
+                                    this.GpuSet.HighTemperatureOn = message.BornOn;
+                                }
+                                if ((message.BornOn - this.GpuSet.HighTemperatureOn).TotalSeconds >= _minerProfile.GpuLETemperatureSeconds) {
+                                    this.GpuSet.HighTemperatureOn = message.BornOn;
+                                    VirtualRoot.ThisLocalWarn(nameof(NTMinerContext), $"自动开始挖矿,因为 GPU 温度连续{_minerProfile.GpuLETemperatureSeconds.ToString()}秒不高于{_minerProfile.GpuStartTemperature.ToString()}℃", toConsole: true);
+                                    StartMine();
+                                }
+                            }
+                        }
+                    }
+                    #endregion
+                });
+        }
+
+        private IGpu GetMaxTemperatureGpu() {
+            if (GpuSet.Count == 0) {
+                return Gpu.GpuAll;
+            }
+            int maxTemperature = int.MinValue;
+            IGpu gpu = Gpu.GpuAll;
+            foreach (var item in GpuSet.AsEnumerable()) {
+                if (item.Temperature > maxTemperature) {
+                    maxTemperature = item.Temperature;
+                    gpu = item;
+                }
+            }
+            return gpu;
+        }
+
+        public void GpuTemperatureReset() {
+            DateTime now = DateTime.Now;
+            this.GpuSet.LowTemperatureOn = DateTime.Now;
+            this.GpuSet.HighTemperatureOn = now;
+        }
         #endregion
 
         public ICpuPackage CpuPackage { get; private set; }

+ 5 - 0
src/NTMinerClient/StopMineReason.cs

@@ -26,6 +26,11 @@ namespace NTMiner {
         [Description("CPU温度过高")]
         HighCpuTemperature,
         /// <summary>
+        /// GPU温度过高
+        /// </summary>
+        [Description("GPU温度过高")]
+        HighGpuTemperature,
+        /// <summary>
         /// 用户通过群控远程停止挖矿
         /// </summary>
         [Description("用户通过群控远程停止挖矿")]

+ 6 - 0
src/NTMinerDataSchemas/Core/Profile/IMinerProfile.cs

@@ -62,6 +62,12 @@ namespace NTMiner.Core.Profile {
         bool IsAutoStartByCpu { get; }
         int CpuStartTemperature { get; }
         int CpuLETemperatureSeconds { get; }
+        bool IsAutoStopByGpu { get; }
+        int GpuStopTemperature { get; }
+        int GpuGETemperatureSeconds { get; }
+        bool IsAutoStartByGpu { get; }
+        int GpuStartTemperature { get; }
+        int GpuLETemperatureSeconds { get; }
         bool IsRaiseHighCpuEvent { get; }
         int HighCpuBaseline { get; }
         int HighCpuSeconds { get; }

+ 12 - 1
src/NTMinerDataSchemas/Core/Profile/MinerProfileData.cs

@@ -80,10 +80,16 @@ namespace NTMiner.Core.Profile {
             IsCreateShortcut = true;
             IsAutoStopByCpu = false;
             IsAutoStartByCpu = false;
+            IsAutoStopByGpu = false;
+            IsAutoStartByGpu = false;
             CpuGETemperatureSeconds = 60;
             CpuLETemperatureSeconds = 60;
+            GpuGETemperatureSeconds = 60;
+            GpuLETemperatureSeconds = 60;
             CpuStartTemperature = 40;
             CpuStopTemperature = 65;
+            GpuStartTemperature = 40;
+            GpuStopTemperature = 80;
             IsRaiseHighCpuEvent = true;
             HighCpuBaseline = 80;
             HighCpuSeconds = 10;
@@ -194,7 +200,12 @@ namespace NTMiner.Core.Profile {
         public int CpuStartTemperature { get; set; }
 
         public int CpuLETemperatureSeconds { get; set; }
-
+        public bool IsAutoStopByGpu { get; set; }
+        public int GpuStopTemperature { get; set; }
+        public int GpuGETemperatureSeconds { get; set; }
+        public bool IsAutoStartByGpu { get; set; }
+        public int GpuStartTemperature { get; set; }
+        public int GpuLETemperatureSeconds { get; set; }
         public bool IsRaiseHighCpuEvent { get; set; }
 
         public int HighCpuBaseline { get; set; }