From 1d38fa034c81b2dd717c5bc9f9dcb913ef54b33c Mon Sep 17 00:00:00 2001 From: Matt Moening Date: Fri, 15 Dec 2017 17:52:17 -0800 Subject: [PATCH] Add List of zero-conf telnet connects to allow auto detection of MCConnect --- App.config | 22 ++- MatterControl.csproj | 21 +++ .../Settings/SettingsHelpers.cs | 1 + SlicerConfiguration/SliceSettingsOrganizer.cs | 2 +- SlicerConfiguration/SliceSettingsWidget.cs | 3 + .../SlicerMapping/EngineMappingMatterSlice.cs | 1 + SlicerConfiguration/UIFields/IpAddessField.cs | 127 ++++++++++++++++++ StaticData/SliceSettings/Layouts.txt | 3 + StaticData/SliceSettings/Properties.json | 13 ++ packages.config | 7 + 10 files changed, 192 insertions(+), 8 deletions(-) create mode 100644 SlicerConfiguration/UIFields/IpAddessField.cs diff --git a/App.config b/App.config index 98282d404..e8470174a 100644 --- a/App.config +++ b/App.config @@ -1,21 +1,29 @@ - + - + - + - - + + + + + + + + + + - + - + diff --git a/MatterControl.csproj b/MatterControl.csproj index 30655aad3..cce467a21 100644 --- a/MatterControl.csproj +++ b/MatterControl.csproj @@ -155,6 +155,7 @@ + Form @@ -452,9 +453,25 @@ + + packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll + + + packages\System.Reactive.Interfaces.3.1.1\lib\net45\System.Reactive.Interfaces.dll + + + packages\System.Reactive.Linq.3.1.1\lib\net46\System.Reactive.Linq.dll + + + packages\System.Reactive.PlatformServices.3.1.1\lib\net46\System.Reactive.PlatformServices.dll + + + packages\System.Reactive.Windows.Threading.3.1.1\lib\net45\System.Reactive.Windows.Threading.dll + packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll + @@ -465,6 +482,10 @@ + + + packages\Zeroconf.2.9.0\lib\net45\Zeroconf.dll + diff --git a/SlicerConfiguration/Settings/SettingsHelpers.cs b/SlicerConfiguration/Settings/SettingsHelpers.cs index 7d6845a18..ee0032145 100644 --- a/SlicerConfiguration/Settings/SettingsHelpers.cs +++ b/SlicerConfiguration/Settings/SettingsHelpers.cs @@ -87,6 +87,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public const string has_sd_card_reader = nameof(has_sd_card_reader); public const string heat_extruder_before_homing = nameof(heat_extruder_before_homing); public const string include_firmware_updater = nameof(include_firmware_updater); + public const string selector_ip_address = nameof(selector_ip_address); public const string ip_address = nameof(ip_address); public const string ip_port = nameof(ip_port); public const string layer_gcode = nameof(layer_gcode); diff --git a/SlicerConfiguration/SliceSettingsOrganizer.cs b/SlicerConfiguration/SliceSettingsOrganizer.cs index 608ffa482..43818e092 100644 --- a/SlicerConfiguration/SliceSettingsOrganizer.cs +++ b/SlicerConfiguration/SliceSettingsOrganizer.cs @@ -46,7 +46,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration public class SliceSettingData { [JsonConverter(typeof(StringEnumConverter))] - public enum DataEditTypes { STRING, INT, INT_OR_MM, DOUBLE, POSITIVE_DOUBLE, OFFSET, DOUBLE_OR_PERCENT, VECTOR2, OFFSET2, CHECK_BOX, LIST, MULTI_LINE_TEXT, HARDWARE_PRESENT, COM_PORT }; + public enum DataEditTypes { STRING, INT, INT_OR_MM, DOUBLE, POSITIVE_DOUBLE, OFFSET, DOUBLE_OR_PERCENT, VECTOR2, OFFSET2, CHECK_BOX, LIST, MULTI_LINE_TEXT, HARDWARE_PRESENT, COM_PORT, IP_LIST }; public string SlicerConfigName { get; set; } diff --git a/SlicerConfiguration/SliceSettingsWidget.cs b/SlicerConfiguration/SliceSettingsWidget.cs index c990485eb..2403f197b 100644 --- a/SlicerConfiguration/SliceSettingsWidget.cs +++ b/SlicerConfiguration/SliceSettingsWidget.cs @@ -606,6 +606,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration uiField = new ExtruderOffsetField(settingsContext, settingData.SlicerConfigName); break; + case SliceSettingData.DataEditTypes.IP_LIST: + uiField = new IpAddessField(printer); + break; default: // Missing Setting settingsRow.AddContent(new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString())) diff --git a/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs b/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs index 7396c69f0..593ec866f 100644 --- a/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs +++ b/SlicerConfiguration/SlicerMapping/EngineMappingMatterSlice.cs @@ -136,6 +136,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration new VisibleButNotMappedToEngine("solid_shell"), new VisibleButNotMappedToEngine(SettingsKey.laser_speed_025), new VisibleButNotMappedToEngine(SettingsKey.laser_speed_100), + new VisibleButNotMappedToEngine("selector_ip_address"), }; matterSliceSettingNames = new HashSet(mappedSettings.Select(m => m.CanonicalSettingsName)); diff --git a/SlicerConfiguration/UIFields/IpAddessField.cs b/SlicerConfiguration/UIFields/IpAddessField.cs new file mode 100644 index 000000000..d54875a75 --- /dev/null +++ b/SlicerConfiguration/UIFields/IpAddessField.cs @@ -0,0 +1,127 @@ +using MatterHackers.Agg; +using MatterHackers.Agg.UI; +using MatterHackers.Localizations; +using MatterHackers.MatterControl.PrinterCommunication; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using MatterHackers.SerialPortCommunication.FrostedSerial; +using Zeroconf; + +namespace MatterHackers.MatterControl.SlicerConfiguration +{ + class IpAddessField : UIField + { + private DropDownList dropdownList; + + private PrinterConfig printer; + + public IpAddessField(PrinterConfig printer) + { + this.printer = printer; + } + + public override void Initialize(int tabIndex) + { + EventHandler unregisterEvents = null; + + base.Initialize(tabIndex); + bool canChangeComPort = !printer.Connection.PrinterIsConnected && printer.Connection.CommunicationState != CommunicationStates.AttemptingToConnect; + dropdownList = new DropDownList("Manual".Localize(), maxHeight: 200) + { + ToolTipText = HelpText, + Margin = new BorderDouble(), + TabIndex = tabIndex, + + Enabled = canChangeComPort, + TextColor = canChangeComPort ? ActiveTheme.Instance.PrimaryTextColor : new Color(ActiveTheme.Instance.PrimaryTextColor, 150), + BorderColor = canChangeComPort ? ActiveTheme.Instance.SecondaryTextColor : new Color(ActiveTheme.Instance.SecondaryTextColor, 150), + + + }; + + dropdownList.Click += (s, e) => + { + //this blows up without runonidle + //RebuildMenuItems(); + }; + + RebuildMenuItems(); + + // Prevent droplist interaction when connected + printer.Connection.CommunicationStateChanged.RegisterEvent((s, e) => + { + canChangeComPort = !printer.Connection.PrinterIsConnected && printer.Connection.CommunicationState != CommunicationStates.AttemptingToConnect; + dropdownList.Enabled = canChangeComPort; + dropdownList.TextColor = canChangeComPort ? ActiveTheme.Instance.PrimaryTextColor : new Color(ActiveTheme.Instance.PrimaryTextColor, 150); + dropdownList.BorderColor = canChangeComPort ? ActiveTheme.Instance.SecondaryTextColor : new Color(ActiveTheme.Instance.SecondaryTextColor, 150); + }, ref unregisterEvents); + + // Release event listener on close + dropdownList.Closed += (s, e) => + { + unregisterEvents?.Invoke(null, null); + }; + + this.Content = dropdownList; + } + + protected override void OnValueChanged(FieldChangedEventArgs fieldChangedEventArgs) + { + dropdownList.SelectedLabel = this.Value; + base.OnValueChanged(fieldChangedEventArgs); + } + + private void RebuildMenuItems() + { + IReadOnlyList possibleHosts = ProbeForNetworkedTelenetConnections().Result; + dropdownList.MenuItems.Clear(); + MenuItem defaultOption = dropdownList.AddItem("Manual", "127.0.0.1:23"); + defaultOption.Selected += (sender, e) => + { + printer.Settings.SetValue(SettingsKey.selector_ip_address,defaultOption.Text); + }; + foreach (Zeroconf.IZeroconfHost host in possibleHosts) + { + // Add each found telnet host to the dropdown list + IService service; + bool exists = host.Services.TryGetValue("_telnet._tcp.local.", out service); + int port = exists ? service.Port:23; + MenuItem newItem = dropdownList.AddItem(host.DisplayName, $"{host.IPAddress}:{port}"); //The port may be unnecessary + // When the given menu item is selected, save its value back into settings + newItem.Selected += (sender, e) => + { + if (sender is MenuItem menuItem) + { + //this.SetValue( + // menuItem.Text, + // userInitiated: true); + string[] ipAndPort = menuItem.Value.Split(':'); + printer.Settings.SetValue(SettingsKey.ip_address, ipAndPort[0]); + printer.Settings.SetValue(SettingsKey.ip_port, ipAndPort[1]); + printer.Settings.SetValue(SettingsKey.selector_ip_address, menuItem.Text); + } + }; + } + + } + + private void DefaultOption_Selected(object sender, EventArgs e) + { + throw new NotImplementedException(); + } + + public static async Task> ProbeForNetworkedTelenetConnections() + { + return await ZeroconfResolver.ResolveAsync("_telnet._tcp.local."); + } + + public static async Task> EnumerateAllServicesFromAllHosts() + { + ILookup domains = await ZeroconfResolver.BrowseDomainsAsync(); + return await ZeroconfResolver.ResolveAsync(domains.Select(g => g.Key)); + } + } +} diff --git a/StaticData/SliceSettings/Layouts.txt b/StaticData/SliceSettings/Layouts.txt index fc43f4441..440574a8d 100644 --- a/StaticData/SliceSettings/Layouts.txt +++ b/StaticData/SliceSettings/Layouts.txt @@ -15,6 +15,7 @@ Simple auto_connect baud_rate com_port + selector_ip_address ip_address ip_port Intermediate @@ -81,6 +82,7 @@ Intermediate auto_connect baud_rate com_port + selector_ip_address ip_address ip_port Advanced @@ -266,6 +268,7 @@ Advanced auto_connect baud_rate com_port + selector_ip_address ip_address ip_port Print Area diff --git a/StaticData/SliceSettings/Properties.json b/StaticData/SliceSettings/Properties.json index 0ad9f2c48..e71255ee9 100644 --- a/StaticData/SliceSettings/Properties.json +++ b/StaticData/SliceSettings/Properties.json @@ -1826,6 +1826,17 @@ "RebuildGCodeOnChange": false, "ReloadUiWhenChanged": true }, + { + "SlicerConfigName": "selector_ip_address", + "PresentationName": "IP Finder", + "HelpText": "List of IP's discovered on the network", + "DataEditType": "IP_LIST", + "ShowAsOverride": false, + "ShowIfSet": "enable_network_printing", + "DefaultValue": "Manual", + "RebuildGCodeOnChange": false, + "ReloadUiWhenChanged": true + }, { "SlicerConfigName": "ip_address", "PresentationName": "IP Address", @@ -1833,6 +1844,7 @@ "DataEditType": "STRING", "ShowAsOverride": false, "ShowIfSet": "enable_network_printing", + "EnableIfSet": "selector_ip_address=Manual", "DefaultValue": "127.0.0.1", "RebuildGCodeOnChange": false }, @@ -1843,6 +1855,7 @@ "DataEditType": "INT", "ShowAsOverride": false, "ShowIfSet": "enable_network_printing", + "EnableIfSet": "selector_ip_address=Manual", "DefaultValue": "23", "RebuildGCodeOnChange": false }, diff --git a/packages.config b/packages.config index d01982fbb..1679dbf39 100644 --- a/packages.config +++ b/packages.config @@ -2,5 +2,12 @@ + + + + + + + \ No newline at end of file