After I made his new house smart with my son-in-law, I also wanted to get the Shelly® relays for my own house.
I mainly control these devices with the Amazon Echo Dot® ("Alexa
") - but out of interest and because there is no good documentation to be found, I decided to create routines based on .NET also make it possible to control or query the devices.
In this article, I present the routines I created for this purpose and name the peculiarities that the modules I use have.
The Shelly 2.5, Shelly Dimmer2, Shelly 1PM and Shelly 2PM modules are used in my house. I created the routines for these modules. Of course, there are a few other modules - but the valued reader would then have to create the routines for them himself, possibly using this template.
Since I only have Visual Studio 2010® at my disposal, the framework used here is .NET 4.0
Basics
Basically, communication with the devices takes place via HTML commands. The feedback from the devices themselves is provided as a JSON string
for which I have stored the information that interests me in appropriate subclasses. Unfortunately, the partial commands vary from device to device, which is why I had to create specific routines for each device.
I assume basic knowledge of the deserialization of JSON string
s here. I won't go into the use of the WebClient
any further.
With Which Device Am I "Speaking?"
Private Class ShellyTyp
Public type As String
Public app As String
ReadOnly Property Typ() As String
Get
If type IsNot Nothing Then Return type
If app IsNot Nothing Then Return app
Return ""
End Get
End Property
End Class
Function Shelly_GetType(IpAdress As String) As ShellyType
Request = "http://" + IpAdress + "/shelly"
Dim myType As ShellyType = ShellyType.None
Try
Dim result As String = webClient.DownloadString(Request)
Dim JSON_Packet As ShellyTyp = _
JsonConvert.DeserializeObject(Of ShellyTyp)(result)
Select Case JSON_Packet.Typ
Case "SHSW-25" : myType = ShellyType.Shelly_25
Case "SHDM-2" : myType = ShellyType.Shelly_Dimmer2
Case "Plus1PM", "Plus1Mini" : myType = ShellyType.Shelly_1PM
Case "Plus2PM" : myType = ShellyType.Shelly_2PM
End Select
Return myType
Catch ex As Exception
Return ShellyType.None
End Try
End Function
private class JSON_ShellyType
{
public string type = "";
public string app = "";
public string Typ
{
get
{
if (type != "")
return type;
if (app != "")
return app;
return "";
}
}
}
public static ShellyType Shelly_GetType(string IpAdress)
{
Request = "http://" + IpAdress + "/shelly";
ShellyType myType = ShellyType.None;
try
{
string result = webClient.DownloadString(Request);
JSON_ShellyType JSON_Packet = JsonConvert.DeserializeObject<JSON_ShellyType>(result);
switch (JSON_Packet.Typ)
{
case "SHSW-25":
{
myType = ShellyType.Shelly_25;
break;
}
case "SHDM-2":
{
myType = ShellyType.Shelly_Dimmer2;
break;
}
case "Plus1PM":
case "Plus1Mini":
{
myType = ShellyType.Shelly_1PM;
break;
}
case "Plus2PM":
{
myType = ShellyType.Shelly_2PM;
break;
}
}
return myType;
}
catch (Exception)
{
return ShellyType.None;
}
}
As can be seen here, there is a common command for the type query for all devices. The type response is again stored in different JSON properties depending on the device - for some devices in the "type
" item and for some devices in the "app
" item. The JSON deserialize then fills either one or the other item in my class.
The function shown returns me the respective type for. I use this query in all later queries/commands.
Request of the Device Status
Function Shelly_GetStatus(IpAdress As String) As IO_Status
Dim myType As ShellyType = Shelly_GetType(IpAdress)
Select Case myType
Case ShellyType.Shelly_25
Return Shelly_25_GetStatus(IpAdress)
Case ShellyType.Shelly_Dimmer2
Return Shelly_Dimmer2_GetStatus(IpAdress)
Case ShellyType.Shelly_1PM
Return Shelly_1PM_GetStatus(IpAdress)
Case ShellyType.Shelly_2PM
Return Shelly_2PM_GetStatus(IpAdress)
Case ShellyType.None
Return New IO_Status
End Select
Return New IO_Status
End Function
Class IO_Status
Public Connection As ShellyResult = ShellyResult.None
Public In0 As Boolean = False
Public In1 As Boolean = False
Public Out0 As Boolean = False
Public Out1 As Boolean = False
Public Mode As ShellyMode = ShellyMode.none
Public OutValue As Integer = -1
Overrides Function toString() As String
Dim s As String = Connection.ToString
Dim inActive As String = ""
If In0 Then inActive += "0"
If In1 Then inActive += "1"
If inActive < > "" Then s += ", in:" + inActive
Dim outActive As String = ""
If Out0 Then outActive += "0"
If Out1 Then outActive += "1"
If outActive < > "" Then s += ", out:" + outActive
If OutValue > = 0 Then s += ", " + Str(OutValue).Trim + "%"
If Mode < > ShellyMode.none Then s += ", mode:" + Mode.ToString
Return s
End Function
End Class
public static Shelly_IOStatus Shelly_GetStatus(string IpAdress)
{
ShellyType myType = Shelly_GetType(IpAdress);
switch (myType)
{
case ShellyType.Shelly_25:
{
return Shelly_25_GetStatus(IpAdress);
}
case ShellyType.Shelly_Dimmer2:
{
return Shelly_Dimmer2_GetStatus(IpAdress);
}
case ShellyType.Shelly_1PM:
{
return Shelly_1PM_GetStatus(IpAdress);
}
case ShellyType.Shelly_2PM:
{
return Shelly_2PM_GetStatus(IpAdress);
}
case ShellyType.None:
{
return new Shelly_IOStatus();
}
}
return new Shelly_IOStatus();
}
public class Shelly_IOStatus
{
public ShellyResult Connection = ShellyResult.None;
public bool In0 = false;
public bool In1 = false;
public bool Out0 = false;
public bool Out1 = false;
public ShellyMode Mode = ShellyMode.none;
public ShellyRollerState RollerState = ShellyRollerState.none;
public int OutValue = -1;
public override string ToString()
{
string s = Connection.ToString();
string inActive = "";
if (In0)
inActive += "0";
if (In1)
inActive += "1";
if (inActive != "")
s += ", in:" + inActive;
string outActive = "";
if (Out0)
outActive += "0";
if (Out1)
outActive += "1";
if (outActive != "")
s += ", out:" + outActive;
if (OutValue >= 0)
s += ", " + Convert.ToString(OutValue).Trim() + "%";
if (Mode != ShellyMode.none)
s += ", mode:" + Mode.ToString();
return s;
}
}
The Shelly_GetStatus
function shown here returns the status of the Shelly device at the specified IP address. The function itself branches to the corresponding subfunction according to the respective Shelly type.
In order to achieve standardization here, there is the same IO-status for all devices, only non-existent areas are not assigned in the subfunctions.
Device Status Subfunction
I will describe the sub-function itself here using the example for one of the devices. All other devices only differ in the command and the JSON string
received in response.
In the following example, I use the query of a Shelly-1PM
:
Private Class JSON_Shelly12PM_Status
< Newtonsoft.Json.JsonProperty("switch:0") >
Public Switch0 As cRelay
< Newtonsoft.Json.JsonProperty("switch:1") >
Public Switch1 As cRelay
< Newtonsoft.Json.JsonProperty("cover:0") >
Public Cover0 As cCover
< Newtonsoft.Json.JsonProperty("input:0") >
Public Input0 As cInput
< Newtonsoft.Json.JsonProperty("input:1") >
Public Input1 As cInput
Partial Public Class cRelay
Public output As Boolean
End Class
Partial Public Class cCover
Public state As String
Public last_direction As String
Public current_pos As Integer
End Class
Partial Public Class cInput
Public state As Object
End Class
ReadOnly Property RelayState As Boolean()
Get
Dim myState(1) As Boolean
If Switch0 IsNot Nothing Then myState(0) = Switch0.output
If Switch1 IsNot Nothing Then myState(1) = Switch1.output
If Cover0 IsNot Nothing Then
Select Case Cover0.state
Case "stopped"
myState(0) = False
myState(1) = False
Case "opening"
myState(0) = True
myState(1) = False
Case "closing"
myState(0) = False
myState(1) = True
End Select
End If
Return myState
End Get
End Property
ReadOnly Property InputState As Boolean()
Get
Dim myState(1) As Boolean
If Not Boolean.TryParse(Input0.state, myState(0)) Then myState(0) = False
If Not Boolean.TryParse(Input1.state, myState(1)) Then myState(1) = False
Return myState
End Get
End Property
ReadOnly Property Mode As ShellyMode
Get
If Switch0 IsNot Nothing Then Return ShellyMode.Relay
If Cover0 IsNot Nothing Then Return ShellyMode.Roller
Return ShellyMode.none
End Get
End Property
ReadOnly Property RollerState As ShellyRollerState
Get
If Cover0 IsNot Nothing Then
If(Cover0.state = "stop") And (Cover0.last_direction = "opening") Then Return ShellyRollerState.Stop_AfterOpening
If(Cover0.state = "closing") Then Return ShellyRollerState.Closing
If(Cover0.state = "stop") And (Cover0.last_direction = "closing") Then Return ShellyRollerState.Stop_AfterClosing
If(Cover0.state = "opening") Then Return ShellyRollerState.Opening
End If
Return ShellyRollerState.none
End Get
End Property
End Class
Function Shelly_1PM_GetStatus(IpAdress As String) As IO_Status
Dim myStatus As New IO_Status
Request = "http://" + IpAdress + "/rpc/Shelly.GetStatus"
Try
Dim result As String = webClient.DownloadString(Request)
Dim JSON_Packet As JSON_Shelly12PM_Status =
JsonConvert.DeserializeObject(Of JSON_Shelly12PM_Status)(result)
myStatus.Out0 = JSON_Packet.RelayState(0)
myStatus.Out0 = False
myStatus.OutValue = -1
myStatus.Mode = "Relay"
myStatus.In0 = JSON_Packet.InputState(0)
myStatus.In1 = False
myStatus.Connection = ShellyResult.Connected
Return myStatus
Catch ex As Exception
myStatus.Connection = ShellyResult.ErrorConnection
Return myStatus
End Try
End Function
private class JSON_Shelly12PM_Status
{
[Newtonsoft.Json.JsonProperty("switch:0")]
public cRelay Switch0 = null;
[Newtonsoft.Json.JsonProperty("switch:1")]
public cRelay Switch1 = null;
[Newtonsoft.Json.JsonProperty("cover:0")]
public cCover Cover0 = null;
[Newtonsoft.Json.JsonProperty("input:0")]
public cInput Input0 = null;
[Newtonsoft.Json.JsonProperty("input:1")]
public cInput Input1 = null;
public partial class cRelay
{
public bool output = false;
}
public partial class cCover
{
public string state = "";
public string last_direction = "";
public int current_pos = 0;
}
public partial class cInput
{
public object state = null;
}
public bool[] RelayState
{
get
{
bool[] myState = new bool[2];
if (Switch0 != null)
myState[0] = Switch0.output;
if (Switch1 != null)
myState[1] = Switch1.output;
if (Cover0 != null)
{
switch (Cover0.state)
{
case "stopped":
{
myState[0] = false;
myState[1] = false;
break;
}
case "opening":
{
myState[0] = true;
myState[1] = false;
break;
}
case "closing":
{
myState[0] = false;
myState[1] = true;
break;
}
}
}
return myState;
}
}
public bool[] InputState
{
get
{
bool[] myState = new bool[2];
if (!bool.TryParse(Convert.ToString(Input0.state), out myState[0]))
{
myState[0] = false;
}
if (!bool.TryParse(Convert.ToString(Input1.state), out myState[1]))
{
myState[1] = false;
}
return myState;
}
}
public ShellyMode Mode
{
get
{
if (Switch0 != null)
return ShellyMode.Relay;
if (Cover0 != null)
return ShellyMode.Roller;
return ShellyMode.none;
}
}
public ShellyRollerState RollerState
{
get
{
if (Cover0 != null)
{
if ((Cover0.state == "stop") & (Cover0.last_direction == "opening"))
return ShellyRollerState.Stop_AfterOpening;
if ((Cover0.state == "closing"))
return ShellyRollerState.Closing;
if ((Cover0.state == "stop") & (Cover0.last_direction == "closing"))
return ShellyRollerState.Stop_AfterClosing;
if ((Cover0.state == "opening"))
return ShellyRollerState.Opening;
}
return ShellyRollerState.none;
}
}
}
private static Shelly_IOStatus Shelly_1PM_GetStatus(string IpAdress)
{
Shelly_IOStatus myStatus = new Shelly_IOStatus();
Request = "http://" + IpAdress + "/rpc/Shelly.GetStatus";
try
{
string result = webClient.DownloadString(Request);
JSON_Shelly12PM_Status JSON_Packet = JsonConvert.DeserializeObject<JSON_Shelly12PM_Status>(result);
myStatus.Out0 = JSON_Packet.RelayState[0];
myStatus.Out0 = false;
myStatus.OutValue = -1;
myStatus.Mode = ShellyMode.Relay;
myStatus.In0 = JSON_Packet.InputState[0];
myStatus.In1 = false;
myStatus.Connection = ShellyResult.Connected;
return myStatus;
}
catch (Exception)
{
myStatus.Connection = ShellyResult.ErrorConnection;
return myStatus;
}
}
The Shelly-1PM
is a 1-channel relay with only one input. However, the JSON string
returned by the device itself is no different from that of a Shelly-2PM
- that's why I use the same class for deserialization of the JSON string for both devices.
Controlling a Device / Sending a Command
As an example, I present the function for controlling a relay in Shelly. There is also the option of controlling the brightness of a dimmer and moving a blind to a specific position. However, none of these functions differ in their basics.
Function Shelly_SetOutput(IpAdress As String, OutNr As Integer, State As Boolean ) As ShellyResult
Dim myType As ShellyType = Shelly_GetType(IpAdress)
Request = "http://" + IpAdress + "/relay/"
Select Case myType
Case ShellyType.Shelly_1PM
Request += "0?turn="
If Not State Then
Request += "off"
Else
Request += "on"
End If
Case ShellyType.Shelly_2PM, ShellyType.Shelly_25
Select Case OutNr
Case 0, 1
Request += Str(OutNr).Trim
Case Else
Return ShellyResult.ErrorShellyType
End Select
Request += "?turn="
If Not State Then
Request += "off"
Else
Request += "on"
End If
Case ShellyType.Shelly_Dimmer2
Request = "http://" + IpAdress + "/light/0?turn="
If Not State Then
Request += "off"
Else
Request += "on"
End If
Case Else
Return ShellyResult.NoAction
End Select
Try
Dim result As String = webClient.DownloadString(Request)
Return ShellyResult.Done
Catch ex As Exception
Return ShellyResult.ErrorConnection
End Try
Return ShellyResult.NoAction
End Function
public static ShellyResult Shelly_SetOutput(string IpAdress, int OutNr, bool State)
{
ShellyType myType = Shelly_GetType(IpAdress);
Request = "http://" + IpAdress + "/relay/";
switch (myType)
{
case ShellyType.Shelly_1PM:
{
Request += "0?turn=";
if (!State)
Request += "off";
else
Request += "on";
break;
}
case ShellyType.Shelly_2PM:
case ShellyType.Shelly_25:
{
switch (OutNr)
{
case 0:
case 1:
{
Request += Convert.ToString(OutNr).Trim();
break;
}
default:
{
return ShellyResult.ErrorShellyType;
}
}
Request += "?turn=";
if (!State)
Request += "off";
else
Request += "on";
break;
}
case ShellyType.Shelly_Dimmer2:
{
Request = "http://" + IpAdress + "/light/0?turn=";
if (!State)
Request += "off";
else
Request += "on";
break;
}
default:
{
return ShellyResult.NoAction;
}
}
try
{
string result = webClient.DownloadString(Request);
return ShellyResult.Done;
}
catch (Exception)
{
return ShellyResult.ErrorConnection;
}
}
Integration at a Button-Control
The following code shows the integration of the methods into a button control. In this case, I extend the standard button with some properties and integrate the functions accordingly.
The button now calls the Shelly_ToggleOutput
method at the click event and changes its colors according to the output status of the selected Shelly device.
Imports System.ComponentModel
Public Class ShellyButton
Inherits Button
Sub New()
MyBase.BackColor = my_DefaultBackColor
MyBase.ForeColor = my_DefaultForeColor
End Sub
#Region "Properties"
< Browsable(False), EditorBrowsable(EditorBrowsableState.Never) >
Shadows Property ForeColor As Color
< Category("Shelly"), Description("Default ForeColor of the Control") >
< DefaultValue(GetType(System.Drawing.Color), "Black") >
Property DefaultForeColor As Color
Get
Return my_DefaultForeColor
End Get
Set(ByVal value As Color)
my_DefaultForeColor = value
MyBase.BackColor = value
End Set
End Property
Private my_DefaultForeColor As Color = Color.Black
< Category("Shelly"), Description("ForeColor of the Control when animated") >
< DefaultValue(GetType(System.Drawing.Color), "White") >
Property AnimationForeColor As Color
Get
Return my_AnimationForeColor
End Get
Set(ByVal value As Color)
my_AnimationForeColor = value
End Set
End Property
Private my_AnimationForeColor As Color = Color.White
< Browsable(False), EditorBrowsable(EditorBrowsableState.Never) >
Shadows Property BackColor As Color
< Category("Shelly"), Description("Default BackColor of the Control") >
< DefaultValue(GetType(System.Drawing.Color), "LightGray") >
Property DefaultBackColor As Color
Get
Return my_DefaultBackColor
End Get
Set(ByVal value As Color)
my_DefaultBackColor = value
MyBase.BackColor = value
Me.Invalidate()
End Set
End Property
Private my_DefaultBackColor As Color = Color.LightGray
< Category("Shelly"), Description("BackColor of the Control when animated") >
< DefaultValue(GetType(System.Drawing.Color), "Green") >
Property AnimationBackColor As Color
Get
Return my_AnimationBackColor
End Get
Set(ByVal value As Color)
my_AnimationBackColor = value
Me.Invalidate()
End Set
End Property
Private my_AnimationBackColor As Color = Color.Green
< Category("Shelly"), Description("Refresh-Interval for the Animation") >
< DefaultValue(1000) >
Property RefreshInterval As Integer
Get
Return my_Timer.Interval
End Get
Set(value As Integer)
If value > 500 Then
my_Timer.Interval = value
End If
End Set
End Property
< Category("Shelly"), Description("Enables the Refresh of the Animation") >
< DefaultValue(False) >
Property RefreshEnabled As Boolean
Get
Return my_RefreshEnabled
End Get
Set(value As Boolean)
my_RefreshEnabled = value
If Not DesignMode Then my_Timer.Enabled = value
End Set
End Property
Private my_RefreshEnabled As Boolean = False
< Category("Shelly"), Description("IpAdress of the Shelly-Device to work with") >
< RefreshProperties(RefreshProperties.All) >
Property IpAdress As String
Get
Return my_IPAdress
End Get
Set(value As String)
my_ShellyType = Shelly_GetType(value).ToString
If my_ShellyType < > "None" Then my_IPAdress = value
End Set
End Property
Private my_IPAdress As String = ""
< Category("Shelly"), Description("Output-Number of the Shelly-Device to work with") >
< DefaultValue(0) >
Property ShellyOutputNr As Integer
Get
Return my_ShellyOutputNr
End Get
Set(value As Integer)
If(value > = 0) And(value < = 1) Then my_ShellyOutputNr = value
End Set
End Property
Private my_ShellyOutputNr As Integer = 0
< Category("Shelly"), Description("shows the Type of the connected Shelly-Device") >
ReadOnly Property ShellyType As String
Get
Return my_ShellyType
End Get
End Property
Private my_ShellyType As String
#End Region
#Region "Methods"
call the ToggleButton - Method with the Button - Click
Protected Overrides Sub OnClick(e As System.EventArgs)
Dim result As ShellyResult = Shelly_ToggleOutput(my_IPAdress, my_ShellyOutputNr)
End Sub
Sub Timer_Tick() Handles my_Timer.Tick
my_Status = Shelly_GetStatus(my_IPAdress)
my_OutActive =(my_ShellyOutputNr = 0 And my_Status.Out0)
Or (my_ShellyOutputNr = 1 And my_Status.Out1) If my_OutActive Then
MyBase.BackColor = my_AnimationBackColor
MyBase.ForeColor = my_AnimationForeColor
Else
MyBase.BackColor = my_DefaultBackColor
MyBase.ForeColor = my_DefaultForeColor
End If
End Sub
Private my_Status As Shelly_IOStatus
Private my_OutActive As Boolean = False
Private WithEvents my_Timer As New Timer With {.Enabled = False, .Interval = 1000}
#End Region
End Class
using System;
using System.Drawing;
using System.Windows.Forms;
using System.ComponentModel;
using ShellyConnect_C;
public class ShellyButton : System.Windows.Forms.Button
{
public ShellyButton()
{
my_Timer = new System.Windows.Forms.Timer()
{
Enabled = false,
Interval = 1000
};
my_Timer.Tick += Timer_Tick;
base.BackColor = my_DefaultBackColor;
base.ForeColor = my_DefaultForeColor;
}
[Browsable(false)][EditorBrowsable(EditorBrowsableState.Never)]
public new Color ForeColor { get; set; }
[Category("Shelly")]
[Description("Default ForeColor of the Control ")]
[DefaultValue(typeof(System.Drawing.Color), "Black")]
public new Color DefaultForeColor
{
get
{
return my_DefaultForeColor;
}
set
{
my_DefaultForeColor = value;
base.BackColor = value;
}
}
private Color my_DefaultForeColor = Color.Black;
[Category("Shelly")]
[Description("ForeColor of the Control when animated ")]
[DefaultValue(typeof(System.Drawing.Color), "White")]
public Color AnimationForeColor
{
get
{
return my_AnimationForeColor;
}
set
{
my_AnimationForeColor = value;
}
}
private Color my_AnimationForeColor = Color.White;
[Browsable(false)][EditorBrowsable(EditorBrowsableState.Never)]
public new Color BackColor { get; set; }
[Category("Shelly")]
[Description("Default BackColor of the Control ")]
[DefaultValue(typeof(System.Drawing.Color), "LightGray")]
public new Color DefaultBackColor
{
get
{
return my_DefaultBackColor;
}
set
{
my_DefaultBackColor = value;
base.BackColor = value;
this.Invalidate();
}
}
private Color my_DefaultBackColor = Color.LightGray;
[Category("Shelly")]
[Description("BackColor of the Control when animated ")]
[DefaultValue(typeof(System.Drawing.Color), "Green")]
public Color AnimationBackColor
{
get
{
return my_AnimationBackColor;
}
set
{
my_AnimationBackColor = value;
this.Invalidate();
}
}
private Color my_AnimationBackColor = Color.Green;
[Category("Shelly")]
[Description("Refresh-Interval for the Animation ")]
[DefaultValue(1000)]
public int RefreshInterval
{
get
{
return my_Timer.Interval;
}
set
{
if (value > 500)
my_Timer.Interval = value;
}
}
[Category("Shelly")]
[Description("Enables the Refresh of the Animation")]
[DefaultValue(false)]
public bool RefreshEnabled
{
get
{
return my_RefreshEnabled;
}
set
{
my_RefreshEnabled = value;
if (!DesignMode)
my_Timer.Enabled = value;
}
}
private bool my_RefreshEnabled = false;
[Category("Shelly")]
[Description("IpAdress of the Shelly - Device to work with ")]
[RefreshProperties(RefreshProperties.All)]
public string IpAdress
{
get
{
return my_IPAdress;
}
set
{
ShellyCom.ShellyType myType = ShellyCom.Shelly_GetType(value);
my_ShellyType = Convert.ToString(myType);
if (my_ShellyType != "None")
my_IPAdress = value;
}
}
private string my_IPAdress = "192.168.178.201";
[Category("Shelly")]
[Description("Output-Number of the Shelly - Device to work with ")]
[DefaultValue(0)]
public int ShellyOutputNr
{
get
{
return my_ShellyOutputNr;
}
set
{
if ((value >= 0) & (value <= 1))
my_ShellyOutputNr = value;
}
}
private int my_ShellyOutputNr = 0;
[Category("Shelly")]
[Description("shows the Type of the connected Shelly - Device ")]
public string ShellyType
{
get
{
return my_ShellyType;
}
}
private string my_ShellyType;
protected override void OnClick(System.EventArgs e)
{
ShellyCom.ShellyResult result = ShellyCom.Shelly_ToggleOutput(my_IPAdress, my_ShellyOutputNr);
}
public void Timer_Tick(object sender, System.EventArgs e)
{
my_Status = ShellyCom.Shelly_GetStatus(my_IPAdress);
my_OutActive = (my_ShellyOutputNr == 0 & my_Status.Out0) | (my_ShellyOutputNr == 1 & my_Status.Out1);
if (my_OutActive)
{
base.BackColor = my_AnimationBackColor;
base.ForeColor = my_AnimationForeColor;
}
else
{
base.BackColor = my_DefaultBackColor;
base.ForeColor = my_DefaultForeColor;
}
}
private ShellyCom.Shelly_IOStatus my_Status;
private bool my_OutActive = false;
private Timer my_Timer;
}
Points of Interest
Overall, the following methods are included:
Shelly_GetStatusString | passes the complete and formatted result string to the selected request |
Shelly_GetType | passes the type of Shelly device at the selected IP address |
Shelly_GetStatus | transfers the current device status of the Shelly device to the selected IP address the corresponding characteristics are returned in the Shelly_IOStatus Depending on the device type, the sub-methods are used:
Shelly_25_GetStatus : get the state of a Shelly 2.5 Shelly_25_convertJSON : convert the JSON-String of the Shelly 2.5 request Shelly_Dimmer2_GetStatus : get the state of a Shelly Dimmer2 Shelly_Dimmer2_convertJSON : convert the JSON-String of the Shelly Dimmer2 request Shelly_1PM_GetStatus : get the state of a Shelly 1PM Shelly_1PM_convertJSON : convert the JSON-String of the Shelly 1PM request Shelly_2PM_GetStatus : get the state of a Shelly 2PM Shelly_2PM_convertJSON : convert the JSON-String of the Shelly 2PM request
|
Shelly_SetOutput | sets the selected output on the Shelly device at the selected IP address to the selected status |
Shelly_ToggleOutput | toggles the status of the selected output on the Shelly device at the selected IP address |
Shelly_SetRoller | sets the blinds / rollers to the selected position on the Shelly device at the selected IP address |
Shelly_ToggleRoller | toggles the driving status of the blind / roller to the selected position on the Shelly device at the selected IP address |
Shelly_SetDimmer | controls the dimmer on the Shelly device at the selected IP address to the selected brightness value |
with the return types:
Enum ShellyType | the possible Shelly-Types |
Enum ShellyResult | the possible results of a request |
Enum ShellyMode | the possible operating modes of the Shelly device |
Enum ShellyRollerState | the possible states of the blind / roller drive |
Class Shelly IOStatus | the IO-Status of the requested Shelly device |
Finally – Last Words
I like to thank @RichardDeeming and @Andre Oosthuizen for assistance with some details I didn't know.
I obtained basic information about the devices themselves from the Page Shelly Support.
I had to determine the item names of the queries myself using reverse engineering.
History
- 23rd November, 2023: Initial version