Announcement

Collapse
No announcement yet.

Miele@Home script

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Miele@Home script

    I made a script that connects to the Miele@Home proxy server and deserialise the JSON that is returned.
    Your device had to support Miele@Home wifi and you must create a Miele dev account.
    For more info check this link https://www.miele.com/developer/

    If you want to use this script you have to do the following things:
    - create 14 devices (or modify the script and create more/less) and fill in the device ID in the script.
    - fill in your Miele client ID and secret
    - fill in your Miele username and password
    - fill in your Miele serial number of the device
    - fill in your event name (this is used to disable the event in case the token is refreshed more then once a day).
    - fill in a from and to email address (or modify the script and use an other medium)
    - this script uses JavaScriptSerializer so the line ScriptingReferences=System.Web.Script.Serialization;System.W eb.Extensions.dll has to be in your settings.ini file

    It has a debug in case you need to troubleshoot your json string

    I've created a recurring event that runs the script. If it's the first time you use this script the token is generated and put in a device string.

    Disclaimer: I'm not a programmer if this script sets your house on fire I'm not responsible.

    Click image for larger version  Name:	Screenshot 2019-06-05 at 11.06.44.png Views:	0 Size:	144.7 KB ID:	1308902

    Code:
    Imports System.IO
    Imports System.Net
    Imports System.Web
    Imports System.Web.Script.Serialization
    
    Sub Main(ByVal Parm As Object)
    
        Dim SN_Device As String = "SERIALNUMBER-OF-DEVICE"
        Dim debug As Boolean = False
    
        Dim myWebReq As HttpWebRequest
        Dim myWebResp As HttpWebResponse
        Dim sr As StreamReader
        Dim strURL As String = "https://api.mcs3.miele.com/v1/devices/" & SN_Device
        Dim json As New JavaScriptSerializer
    
        Dim devID1 As Integer = DEVICE-ID     'Device
        Dim devID2 As Integer = DEVICE-ID     'Firmware
        Dim devID3 As Integer = DEVICE-ID     'Status
        Dim devID4 As Integer = DEVICE-ID     'Program
        Dim devID5 As Integer = DEVICE-ID     'Target Temperature
        Dim devID6 As Integer = DEVICE-ID     'Remote Control
        Dim devID7 As Integer = DEVICE-ID     'Smart Grid
        Dim devID8 As Integer = DEVICE-ID     'Spinning Speed
        Dim devID9 As Integer = DEVICE-ID     'Remaining Time
        Dim devID10 As Integer = DEVICE-ID    'Start Time
        Dim devID11 As Integer = DEVICE-ID    'Start Time Countdown
        Dim devID12 As Integer = DEVICE-ID    'Elapsed Time
        Dim devID13 As Integer = DEVICE-ID    'End Time
        Dim devID14 As Integer = DEVICE-ID    'Token
    
    
        Try
            Dim Token As String = hs.DeviceString(devID14)
            myWebReq = DirectCast(WebRequest.Create(strURL), HttpWebRequest)
            myWebReq.Method = "GET"
            myWebReq.Headers("Accept-Encoding") = "application/jsonAuthorization"
            myWebReq.Headers("Authorization") = "Bearer " & Token
            myWebReq.Timeout = 5000
            myWebResp = DirectCast(myWebReq.GetResponse(), HttpWebResponse)
            sr = New StreamReader(myWebResp.GetResponseStream())
            Dim responseText As String = sr.ReadToEnd()
    
                If debug = True Then
                    hs.WriteLog("Miele", responseText)
                End If
            sr.Close
    
          Dim dataObj As jsonStructure = json.Deserialize(Of jsonStructure)(responseText)
    
                If debug = True Then
                    hs.writelog("Miele", "-----------Debug------------")
                    hs.writelog("Miele", "Device: " & (dataObj.Ident.Type.value_localized).ToString)
                    hs.writelog("Miele", "Serialnumber: " & (dataObj.Ident.deviceIdentLabel.fabNumber).ToString)
                    hs.writelog("Miele", "Type: " & (dataObj.Ident.deviceIdentLabel.techType).ToString)
                    hs.writelog("Miele", "Firmware: " & (dataObj.Ident.xkmIdentLabel.releaseVersion).ToString)
                    hs.writelog("Miele", "Status: " & (dataObj.State.Status.value_localized).ToString)
                    hs.writelog("Miele", "Status Raw: " & (dataObj.State.Status.value_raw).ToString)
                    hs.writelog("Miele", "Program: " & (dataObj.State.ProgramType.value_localized).ToString)
                    hs.writelog("Miele", "Start Time Hours: " & (dataObj.State.startTime(0)).ToString)
                    hs.writelog("Miele", "Start Time Minutes: " & (dataObj.State.startTime(1)).ToString)
                    hs.writelog("Miele", "Remaining Time Hours: " & (dataObj.State.remainingTime(0)).ToString)
                    hs.writelog("Miele", "Remaining Time Minutes : " & (dataObj.State.remainingTime(1)).ToString)
                    hs.writelog("Miele", "Elapsed Time Hours: " & (dataObj.State.elapsedTime(0)).ToString)
                    hs.writelog("Miele", "Elapsed Time Minutes: " & (dataObj.State.elapsedTime(1)).ToString)
                    hs.writelog("Miele", "Target Temperature: " & (dataObj.State.TargetTemperature(0).value_raw).ToString)
                    hs.writelog("Miele", "Temperature: " & (dataObj.State.Temperature(0).value_raw).ToString)
                    hs.writelog("Miele", "Remotecontrol: " & (dataObj.State.RemoteEnable.fullRemoteControl).ToString)
                    hs.writelog("Miele", "Smartgrid: " & (dataObj.State.RemoteEnable.smartGrid).ToString)
                    hs.writelog("Miele", "Spinningspeed: " & (dataObj.State.spinningSpeed).ToString)
                    hs.writelog("Miele", "Dryingstep: " & (dataObj.State.DryingStep.value_localized).ToString)
                    hs.writelog("Miele", "Ventilation: " & (dataObj.State.VentilationStep.value_localized).ToString)
                    hs.writelog("Miele", "-----------Debug------------")
                End If
    
            Dim StatusVal As Integer = (dataObj.State.Status.value_raw)
    
            Dim StartTime As Integer = (((dataObj.State.startTime(0)) * 60) + (dataObj.State.startTime(1)))
            Dim StartTimeStr As String
                If StartTime > 0 And (StatusVal = 5 OR StatusVal = 4) Then
                    Dim StartTimeDate As Date = DateTime.Now.AddMinutes(StartTime)
                    StartTimeStr = (StartTimeDate.ToString("HH:mm"))
                Else
                    StartTimeStr = "-"
                End If
    
            Dim EndTime As Integer = (((dataObj.State.remainingTime(0)) * 60) + (dataObj.State.remainingTime(1)))
            Dim EndTimeStr As String 
                If EndTime > 0  And (StatusVal = 5 OR StatusVal = 4) Then
                    Dim EndTimeDate As Date = DateTime.Now.AddMinutes(StartTime + EndTime)
                    EndTimeStr = (EndTimeDate.ToString("HH:mm"))
                Else
                    EndTimeStr = "-"
                End If
    
            Dim RC As Boolean = (dataObj.State.RemoteEnable.fullRemoteControl)
            Dim RCval As Integer
                If RC = True Then
                    RCval = 100
                ElseIf RC = False Then
                    RCval = 0
                End If
    
            Dim SG As Boolean = (dataObj.State.RemoteEnable.smartGrid)
            Dim SGval As Integer
                If SG = True Then
                    SGval = 100
                ElseIf SG = False Then
                    SGval = 0
                End If
                If debug = False Then
                    hs.SetDeviceString(devID1, (dataObj.Ident.Type.value_localized), True)
                    hs.SetDeviceValueByRef(devID2, (dataObj.Ident.xkmIdentLabel.releaseVersion), True)
                    hs.SetDeviceValueByRef(devID3, StatusVal, True)
                    hs.SetDeviceString(devID4, (dataObj.State.ProgramType.value_localized), True)
                    hs.SetDeviceValueByRef(devID5, ((dataObj.State.TargetTemperature(0).value_raw) / 100), True)
                    hs.SetDeviceValueByRef(devID6, RCval, True)
                    hs.SetDeviceValueByRef(devID7, SGval, True)
                    hs.SetDeviceValueByRef(devID8, (dataObj.State.spinningSpeed), True)
                    hs.SetDeviceString(devID10, StartTimeStr, True)
                    hs.SetDeviceString(devID13, EndTimeStr, True)
    
                        If StatusVal = 5 OR StatusVal = 4 Then
                            hs.SetDeviceValueByRef(devID9, ((dataObj.State.remainingTime(0)) * 60) + (dataObj.State.remainingTime(1)), True)
                            hs.SetDeviceValueByRef(devID11, ((dataObj.State.startTime(0)) * 60) + (dataObj.State.startTime(1)), True)
                            hs.SetDeviceValueByRef(devID12, ((dataObj.State.elapsedTime(0)) * 60) + (dataObj.State.elapsedTime(1)), True)
                        Else
                            hs.SetDeviceValueByRef(devID9, 0, True)
                            hs.SetDeviceValueByRef(devID11, 0, True)
                            hs.SetDeviceValueByRef(devID12, 0, True)
                        End If
                End If
    
         Catch ex As Exception
            hs.WriteLog("warning", "Miele: " & ex.Message)
                If ex.Message.ToString = "The remote server returned an error: (401) Unauthorized." Then
                    GetToken(devID14)
                End If
        End Try
    End Sub
    
     Public Class Type
            Public key_localized As String
            Public value_raw As Integer
            Public value_localized As String
        End Class
    
        Public Class DeviceIdentLabel
            Public fabNumber As String
            Public fabIndex As String
            Public techType As String
            Public matNumber As String
            Public swids As String()
        End Class
    
        Public Class XkmIdentLabel
            Public techType As String
            Public releaseVersion As Double
        End Class
    
        Public Class Ident
            Public type As Type
            Public deviceName As String
            Public deviceIdentLabel As DeviceIdentLabel
            Public xkmIdentLabel As XkmIdentLabel
        End Class
    
        Public Class Status
            Public value_raw As Integer
            Public value_localized As String
            Public key_localized As String
        End Class
    
        Public Class ProgramType
            Public value_raw As Integer
            Public value_localized As String
            Public key_localized As String
        End Class
    
        Public Class ProgramPhase
            Public value_raw As Integer
            Public value_localized As String
            Public key_localized As String
        End Class
    
        Public Class TargetTemperature
            Public value_raw As Integer
            Public value_localized As String
            Public unit As String
        End Class
    
        Public Class Temperature
            Public value_raw As Integer
            Public value_localized As String
            Public unit As String
        End Class
    
        Public Class RemoteEnable
            Public fullRemoteControl As Boolean
            Public smartGrid As Boolean
        End Class
    
        Public Class DryingStep
            Public value_raw As Object
            Public value_localized As String
            Public key_localized As String
        End Class
    
        Public Class VentilationStep
            Public value_raw As Object
            Public value_localized As String
            Public key_localized As String
        End Class
    
        Public Class State
            Public status As Status
            Public programType As ProgramType
            Public programPhase As ProgramPhase
            Public remainingTime As Integer()
            Public startTime As Integer()
            Public targetTemperature As TargetTemperature()
            Public temperature As Temperature()
            Public signalMiele As Boolean
            Public signalFailure As Boolean
            Public signalDoor As Boolean
            Public remoteEnable As RemoteEnable
            Public light As Integer
            Public elapsedTime As Integer()
            Public spinningSpeed As Integer
            Public dryingStep As DryingStep
            Public ventilationStep As VentilationStep
        End Class
    
        Public Class jsonStructure
            Public ident As Ident
            Public state As State
        End Class
    
        Public Class tokenrequest
            Public access_token As String
            Public refresh_token As String
            Public token_type As String
            Public expires_in As Integer
        End Class
    
    
    Private Function GetToken(ByVal devID14 As Integer)
        Dim Client_ID As String = "CLIENT-ID"
        Dim Client_Secret As String = "CLIENT-SECRET"
        Dim Username As String = "USERNAME"
        Dim Password As String = "PASSWORD"
    
        Dim EmailFrom As String = "FROM-EMAIL"
        Dim EmailTo As String = "TO-EMAIL"
        Dim evStr As String = "NAME-OF-CREATED-EVENT"
    
        Username = HttpUtility.UrlEncode(Username)
        Password = HttpUtility.UrlEncode(Password)
        Dim strURL_Post As String = "https://api.mcs3.miele.com/thirdparty/token/?client_id=" & Client_ID & "&client_secret=" & Client_Secret & "&grant_type=password&username=" & Username & "&password=" & Password & "&vg=nl-NL"
        Dim myWebReq As HttpWebRequest
        Dim myWebResp As HttpWebResponse
        Dim sr As StreamReader
        Dim json As New JavaScriptSerializer
    
        Try
            Dim LastChange As Integer = hs.DeviceTime(devID14)
                If LastChange >= 1440 Then
                    myWebReq = DirectCast(WebRequest.Create(strURL_Post), HttpWebRequest)
                    myWebReq.Method = "POST"
                    myWebReq.Headers("Accept-Encoding") = "application/jsonAuthorization; charset=utf-8"
                    myWebReq.ContentType = "application/x-www-form-urlencoded"
                    myWebReq.Timeout = 5000
                    myWebResp = DirectCast(myWebReq.GetResponse(), HttpWebResponse)
                    sr = New StreamReader(myWebResp.GetResponseStream())
                    Dim responseText As String = sr.ReadToEnd()
                    sr.Close
    
                    Dim dataObj As tokenrequest = json.Deserialize(Of tokenrequest)(responseText)
                    Dim Token As String = (dataObj.access_token.ToString)
                    hs.SetDeviceString(devID14, Token, True)
                Else
                    hs.SendEmail (EmailTo, EmailFrom, "", "", "Miele Script Disabled", "More than 1 token refresh within 24 hours", "")
                    hs.DisableEvent(evStr)
                End If
    
         Catch ex As Exception
            hs.WriteLog("warning", "Miele: " & ex.Message)
            hs.DisableEvent(evStr)
            hs.SendEmail (EmailTo, EmailFrom, "", "", "Miele Script Disabled", "Token refresh failed", "")
        End Try
    End Function

  • #2
    John245

    Comment


    • #3
      Originally posted by MattL0 View Post
      Hi Matt,

      Thanks for attending me on this. But I was aware of this as we did a parallel development.

      ---
      John

      Comment


      • #4
        Haa lol! Guess it makes sense..both of you lives in The Netherlands

        Comment


        • #5
          Originally posted by MattL0 View Post
          Haa lol! Guess it makes sense..both of you lives in The Netherlands
          Miele@home is also available in other countries.

          Both implementations has there advantages and disadvantages.

          —-
          John

          Comment


          • #6
            Originally posted by John245 View Post
            Miele@home is also available in other countries.
            Yes but I think Miele is better known in Western Europe.

            Originally posted by John245 View Post
            Both implementations has there advantages and disadvantages.
            I think John's method is easier for users to use and understand, it also creates the devices automatically.

            The script is more customisable but requires a little bit of knowledge.

            Comment

            Working...
            X