Plugins/MELCloud.html

From Domoticz
Jump to: navigation, search

Informations

Page (still) under construction.

Overview

Documentation about MELCloud python module.hreaded so the whole plugin system will wait.

Release Notes

v0.3 : Add Next Update information, MAC Address and Serial Number, Add Horizontal vane, Add Vertival vane, Add Room Temp

V0.2 Add synchronization between MELCloud and Domoticz devices.

V0.1 Initial Release

Installation

Save the code below in a file name plugin.py

# MELCloud Plugin
# Author:     Gysmo, 2017
# Version: 0.5
#   
# Release Notes:
# v0.5 : Upgrade code to be compliant wih new functions
# v0.4 : Search devices in floors, areas and devices
# v0.3 : Add Next Update information, MAC Address  and Serial Number
#		 Add Horizontal vane
#		 Add Vertival vane
#		 Add Room Temp
# v0.2 : Add sync between Domoticz devices and MELCloud devices
#        Usefull if you use your Mitsubishi remote
# v0.1 : Initial release
"""
<plugin key="MELCloud" version="0.5" name="MELCloud plugin" author="gysmo" wikilink="http://www.domoticz.com/wiki/Plugins/MELCloud.html" externallink="http://www.melcloud.com">
    <params>
        <param field="Username" label="Email" width="200px" required="true" />
        <param field="Password" label="Password" width="200px" required="true" />
        <param field="Mode6" label="Debug" width="75px">
            <options>
                <option label="True" value="Debug"/>
                <option label="False" value="Normal"  default="true" />
            </options>
        </param>
    </params>
</plugin>
"""
import Domoticz
import time
import base64
import json
from urllib.parse import urlencode
from urllib.request import Request, urlopen
 
pluginState = "Not Ready"
socketOn = "FALSE"
 
melKey = ""
melDevices = []
melBuildingID = ""
 
domModeLevels = [0,1,3,7,2]
domModePic = [9,15,16,7,11]
 
domMode = {"0":0,"10":1,"20":3,"30":7,"40":2}
domNameMode = "Off|Warm|Cold|Vent|Dry"
 
# Fan Level 5 value 255
domLevelFan = {"0":1,"10":2,"20":3,"30":4,"40":255,"50":0,"60":1}
domNameFan = "Level1|Level2|Level3|Level4|Level5|Auto|Silence"
 
domLevelTemp = {"0":16,"10":17,"20":18,"30":19,"40":20,"50":21,"60":22,"70":23,"80":24,"90":25,"100":26,"110":27,"120":28,"130":29,"140":30,"150":31}
 
domLevelVaneH = {"0":1,"10":2,"20":3,"30":4,"40":5,"50":12,"60":0}
domNameVaneH = "1|2|3|4|5|Swing|Auto"
 
domLevelVaneV = {"0":1,"10":2,"20":3,"30":4,"40":5,"50":7,"60":0}
domNameVaneV = "1|2|3|4|5|Swing|Auto"
 
 
class BasePlugin:
	enabled = False
	def __init__(self):
		#self.var = 123
		return
 
	def onStart(self):
		global melDevices,domNameFan,domNameMode
		Domoticz.Heartbeat(25)
		if Parameters["Mode6"] == "Debug":
			Domoticz.Debugging(1)
		# Define connexion to MELCloud
		self.melLogin()
		self.melListDevices()
		if (len(Devices) == 0):
			# Init Devices
			# Creation of switches
			# Image ID: 7 for fan, 15 for Temp, 16 for Mode
			Domoticz.Debug("Find " + str(len(melDevices)) + " devices in MELCloud")
			for device in melDevices:
				Domoticz.Debug("Creating device: " + device['name'] + " with melID " + str(device['id']))
				# Create Mode switch
				OptionsMode = {"LevelActions": "||||","LevelNames": domNameMode,"LevelOffHidden": "false","SelectorStyle": "1"}
				Domoticz.Device(Name=device['name']+" - Mode", Unit=device['modeID'], TypeName="Selector Switch", Image=16, Options=OptionsMode, Used=1).Create()
				# Create FAN switch
				OptionsFan = {"LevelActions": "|||||","LevelNames": domNameFan,"LevelOffHidden": "false","SelectorStyle": "1"}
				Domoticz.Device(Name=device['name']+" - Fan", Unit=device['fanID'], TypeName="Selector Switch", Image=7, Options=OptionsFan, Used=1).Create()
				# Create Temp switch
				OptionsTemp = {"LevelActions": "|||||||","LevelNames": "16|17|18|19|20|21|22|23|24|25|26|27|28|29|30|31","LevelOffHidden": "false","SelectorStyle": "1"}
				Domoticz.Device(Name=device['name']+" - Temp", Unit=device['thermoID'], TypeName="Selector Switch", Image=15, Options=OptionsTemp, Used=1).Create()
				# Create Vane Horizontal switch
				OptionsVaneH = {"LevelActions": "|||||||","LevelNames": "1|2|3|4|5|Swing|Auto","LevelOffHidden": "false","SelectorStyle": "1"}
				Domoticz.Device(Name=device['name']+" - Horiontal Vane", Unit=device['vaneHozID'], TypeName="Selector Switch", Image=7, Options=OptionsVaneH, Used=1).Create()
				# Create Vane Vertical switch
				OptionsVaneV = {"LevelActions": "|||||||||||||||","LevelNames": "1|2|3|4|5|Swing|Auto","LevelOffHidden": "false","SelectorStyle": "1"}
				Domoticz.Device(Name=device['name']+" - Vertical Vane", Unit=device['vaneVerID'], TypeName="Selector Switch", Image=7, Options=OptionsVaneV, Used=1).Create()
				# Create Room temp switch
				Domoticz.Device(Name=device['name']+" - Room Temp", Unit=device['roomTempID'], TypeName="Temperature", Used=1).Create()
				# Create Unit switch
				Domoticz.Device(Name=device['name']+" - Unit Infos", Unit=device['infosID'], TypeName="Text", Used=1).Create()
				melDeviceStatus = self.melGetStatus(device['id'])
				# Get values from MEL Cloud to init Domoticz switches values
				for level, fan in domLevelFan.items():
					if(fan == melDeviceStatus['SetFanSpeed']):
						setDomFan = level
				for level, temp in domLevelTemp.items():
					if(temp == melDeviceStatus['SetTemperature']):
						setDomTemp = level
				for level, vaneH in domLevelVaneH.items():
					if(vaneH == melDeviceStatus['VaneHorizontal']):
						setDomVaneH = level
				for level, vaneV in domLevelVaneV.items():
					if(vaneV == melDeviceStatus['VaneVertical']):
						setDomVaneV = level
				if(melDeviceStatus['Power'] is True):
					sValue = str(domModeLevels.index(melDeviceStatus['OperationMode'])) + "0"
					Devices[device['modeID']].Update(1,sValue,domModePic[domModeLevels.index(melDeviceStatus['OperationMode'])])
					Devices[device['fanID']].Update(1,setDomFan)
					Devices[device['thermoID']].Update(1,setDomTemp)
					Devices[device['vaneHozID']].Update(1,setDomVaneH)
					Devices[device['vaneVerID']].Update(1,setDomVaneV)
				elif(melDeviceStatus['Power'] is False):
					Devices[device['modeID']].Update(0,"0",9)
					Devices[device['fanID']].Update(0,setDomFan)
					Devices[device['thermoID']].Update(0,setDomTemp)
					Devices[device['vaneHozID']].Update(0,setDomVaneH)
					Devices[device['vaneVerID']].Update(0,setDomVaneV)
				Devices[device['roomTempID']].Update(1,str(melDeviceStatus['RoomTemperature']))
 
	def onStop(self):
		Domoticz.Log("Goobye from MELCloud plugin.")
 
	def onConnect(self, Status, Description):
		Domoticz.Log("onConnect called")
 
	def onMessage(self, Data, Status, Extra):
		Domoticz.Log("onMessage called")
 
	def onCommand(self, Unit, Command, Level, Hue):
		global melDevices
		Domoticz.Debug("onCommand called for Unit " + str(Unit) + ": Parameter '" + str(Command) + "', Level: " + str(Level))
		for device in melDevices:
			for key, value in device.items():
				if(Unit == value):
					if(key == 'modeID'):
						unitFan = Unit + 1
						unitTemp = Unit + 2
						unitVaneH = Unit + 3
						unitVaneV = Unit + 4
						if(Level == 0):
							Domoticz.Debug("Switch Off the unit "+device['name'])
							self.melSetPower(device['id'],"false")
							Devices[Unit].Update(0, str(Level),9)
							Devices[unitFan].Update(0,str(Devices[unitFan].sValue))
							Devices[unitTemp].Update(0,str(Devices[unitTemp].sValue))
							Devices[unitVaneH].Update(0,str(Devices[unitVaneH].sValue))
							Devices[unitVaneV].Update(0,str(Devices[unitVaneV].sValue))
						elif(Level == 10):
							Domoticz.Debug("Set to WARM the unit "+device['name'])
							self.melSetPower(device['id'],"true")
							self.melSetMode(device['id'],1)
							Devices[Unit].Update(1, str(Level),15)
						elif(Level == 20):
							Domoticz.Debug("Set to COLD the unit "+device['name'])
							self.melSetPower(device['id'],"true")
							self.melSetMode(device['id'],3)
							Devices[Unit].Update(1, str(Level),16)
						elif(Level == 30):
							Domoticz.Debug("Set to Vent the unit "+device['name'])
							self.melSetPower(device['id'],"true")
							self.melSetMode(device['id'],7)
							Devices[Unit].Update(1, str(Level),7)
						elif(Level == 40):
							Domoticz.Debug("Set to Dry the unit "+device['name'])
							self.melSetPower(device['id'],"true")
							self.melSetMode(device['id'],2)
							Devices[Unit].Update(1, str(Level),11)
						if(Level != 0):
							Devices[unitFan].Update(1,str(Devices[unitFan].sValue))
							Devices[unitTemp].Update(1,str(Devices[unitTemp].sValue))
							Devices[unitVaneH].Update(1,str(Devices[unitVaneH].sValue))
							Devices[unitVaneV].Update(1,str(Devices[unitVaneV].sValue))
					elif(key == 'fanID'):
						if(Level == 0):
							Domoticz.Debug("Change FAN  to Level 1 for "+device['name'])
							self.melSetFan(device['id'],"1")
						elif(Level == 10):
							Domoticz.Debug("Change FAN  to Level 2 for "+device['name'])
							self.melSetFan(device['id'],"2")
						elif(Level == 20):
							Domoticz.Debug("Change FAN  to Level 3 for "+device['name'])
							self.melSetFan(device['id'],"3")
						elif(Level == 30):
							Domoticz.Debug("Change FAN  to Level 4 for "+device['name'])
							self.melSetFan(device['id'],"4")
						elif(Level == 40):
							Domoticz.Debug("Change FAN  to Silence for "+device['name'])
							self.melSetFan(device['id'],"6")
						elif(Level == 50):
							Domoticz.Debug("Change FAN  to Auto for "+device['name'])
							self.melSetFan(device['id'],"0")
						Devices[Unit].Update(Devices[Unit].nValue, str(Level))
					elif(key == 'thermoID'):
						setTemp = 16
						if(Level != 0):
							setTemp = int(str(Level).strip("0")) + 16
						Domoticz.Debug("Change Temp to " + str(setTemp) + " for "+device['name'])
						self.melSetTemp(device['id'],str(setTemp))
						Devices[Unit].Update(Devices[Unit].nValue, str(Level))
					else:
						Domoticz.Debug("Device not found")
		return True
 
	def onNotification(self, Name, Subject, Text, Status, Priority, Sound, ImageFile):
		Domoticz.Log("Notification: " + Name + "," + Subject + "," + Text + "," + Status + "," + str(Priority) + "," + Sound + "," + ImageFile)
 
	def onDisconnect(self):
		Domoticz.Log("onDisconnect called")
 
	def onHeartbeat(self):
		global melDevices,domLevelTemp,domLevelFan
		Domoticz.Debug("Current MEL Cloud Key ID:"+melKey)
		Domoticz.Debug("Current MEL Building ID:"+ str(melBuildingID))
		for device in melDevices:
			melDeviceStatus = self.melGetStatus(device['id'])
			domCurrentTemp = domLevelTemp[Devices[device['thermoID']].sValue]
			domCurrentFan = domLevelFan[Devices[device['fanID']].sValue]
			domCurrentVaneH = domLevelVaneH[Devices[device['vaneHozID']].sValue]
			domCurrentVaneV = domLevelVaneV[Devices[device['vaneVerID']].sValue]
			Domoticz.Debug("******** "+device['name']+" ********")
			Domoticz.Debug("Sync POWER " + str(melDeviceStatus['Power']) \
				+ " OPERATION MODE " + str(melDeviceStatus['OperationMode']) \
				+ " FAN SPEED " + str(melDeviceStatus['SetFanSpeed']) \
				+ " VANE HOZ " + str(melDeviceStatus['VaneHorizontal']) \
				+ " VANE VER " + str(melDeviceStatus['VaneVertical']) \
				+ " UNIT TEMP " + str(melDeviceStatus['SetTemperature']))
			if(melDeviceStatus['Power'] is True and Devices[device['modeID']].nValue == 0):
				sValue = str(domModeLevels.index(melDeviceStatus['OperationMode'])) + "0"
				Devices[device['modeID']].Update(1,sValue,domModePic[domModeLevels.index(melDeviceStatus['OperationMode'])])
				Devices[device['fanID']].Update(1,str(Devices[device['fanID']].sValue))
				Devices[device['thermoID']].Update(1,str(Devices[device['thermoID']].sValue))
				Devices[device['vaneHozID']].Update(1,str(Devices[device['vaneHozID']].sValue))
				Devices[device['vaneVerID']].Update(1,str(Devices[device['vaneVerID']].sValue))
			elif(melDeviceStatus['Power'] is False and Devices[device['modeID']].nValue == 1):
				Devices[device['modeID']].Update(0,"0",9)
				Devices[device['fanID']].Update(0,str(Devices[device['fanID']].sValue))
				Devices[device['thermoID']].Update(0,str(Devices[device['thermoID']].sValue))
				Devices[device['vaneHozID']].Update(0,str(Devices[device['vaneHozID']].sValue))
				Devices[device['vaneVerID']].Update(0,str(Devices[device['vaneVerID']].sValue))
 
	# Sync fan value from MELCloud to Domoticz
			if(melDeviceStatus['SetFanSpeed'] != domCurrentFan):
				for level, fan in domLevelFan.items():
					if(fan == melDeviceStatus['SetFanSpeed']):
						Devices[device['fanID']].Update(Devices[device['fanID']].nValue,level)
	# Sync Unit temperature value from MELCloud to Domoticz
			if(melDeviceStatus['SetTemperature'] != domCurrentTemp):
				for level, temp in domLevelTemp.items():
					if(temp == melDeviceStatus['SetTemperature']):
						Devices[device['thermoID']].Update(Devices[device['thermoID']].nValue,level)
	# Sync Vane Horizontal value from MELCloud to Domoticz
			if(melDeviceStatus['VaneHorizontal'] != domCurrentVaneH):
				for level, vaneH in domLevelVaneH.items():
					if(vaneH == melDeviceStatus['VaneHorizontal']):
						Devices[device['vaneHozID']].Update(Devices[device['vaneHozID']].nValue,level)
	# Sync Vane Vertical value from MELCloud to Domoticz
			if(melDeviceStatus['VaneVertical'] != domCurrentVaneH):
				for level, vaneV in domLevelVaneV.items():
					if(vaneV == melDeviceStatus['VaneVertical']):
						Devices[device['vaneVerID']].Update(Devices[device['vaneVerID']].nValue,level)
	# Sync Room temperature value from MELCloud to Domoticz
			if(str(melDeviceStatus['RoomTemperature']) != Devices[device['roomTempID']].sValue):
				Devices[device['roomTempID']].Update(1,str(melDeviceStatus['RoomTemperature']))
				Domoticz.Debug("Sync ROOM TEMP" + str(melDeviceStatus['RoomTemperature']))
	# Sync Infos value from MELCloud to Domoticz
			textInfos = "NEXT UPDATE " +  str(melDeviceStatus['NextCommunication']) + "MAC ADDR " + device['macaddr'] + " S/N " + device['sn']
			if(textInfos != str(Devices[device['infosID']].sValue)):
				Devices[device['infosID']].Update(1,textInfos)
			Domoticz.Debug("Infos " + str(Devices[device['infosID']].sValue))
		return True
 
	def melLogin(self):
		global melKey
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Login/ClientLogin"
		post_fields = {'AppVersion': '1.9.3.0', \
					'Language': '7', \
					'CaptchaChallange': '', \
					'CaptchaResponse': '', \
					'Persist': 'true', \
					'Email': Parameters["Username"], \
					'Password': Parameters["Password"]}
		request = Request(url, urlencode(post_fields).encode())
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		if (jsonResponse["ErrorId"] == None):
			melKey = jsonResponse["LoginData"]["ContextKey"]
			Domoticz.Debug("MELCloud Login success. Key ID:"+melKey)
		elif (jsonResponse["ErrorId"] == 1):
			Domoticz.Debug("MELCloud Login fail. Check your username and password")
		else:
			Domoticz.Debug("MELCloud Login fail. Do not knwon the reason")
		return True
 
	def melListDevices(self):
		global melKey, melDevices, melBuildingID
		melDevice = {}
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices"
		headers = {'X-MitsContextKey': melKey}
		request = Request(url,None,headers=headers)
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		unitModeID = 1
		unitFanID = 2
		unitThermoID = 3
		unitVaneHozID = 4
		unitVaneVerID = 5
		unitRoomTempID = 6
		unitInfosID = 7
		for building in jsonResponse:
	#Search in devices
			for device in building["Structure"]["Devices"]:
				melDevice = {}
				melBuildingID = device["BuildingID"]
				melDevice['name'] = device["DeviceName"]
				melDevice['id'] = device["DeviceID"]
				melDevice['macaddr'] = device["MacAddress"]
				melDevice['sn'] = device["SerialNumber"]
				melDevice['modeID'] = unitModeID
				melDevice['fanID'] = unitFanID
				melDevice['thermoID'] = unitThermoID
				melDevice['vaneHozID'] = unitVaneHozID
				melDevice['vaneVerID'] = unitVaneVerID
				melDevice['roomTempID'] = unitRoomTempID
				melDevice['infosID'] = unitInfosID
				melDevices.append(melDevice)
				unitModeID += 7
				unitFanID += 7
				unitThermoID += 7
				unitVaneHozID += 7
				unitVaneVerID += 7
				unitRoomTempID += 7
				unitInfosID += 7
	#Search in areas
			for area in building["Structure"]["Areas"]:
				for device in area["Devices"]:
					melDevice = {}
					melBuildingID = device["BuildingID"]
					melDevice['name'] = device["DeviceName"]
					melDevice['id'] = device["DeviceID"]
					melDevice['macaddr'] = device["MacAddress"]
					melDevice['sn'] = device["SerialNumber"]
					melDevice['modeID'] = unitModeID
					melDevice['fanID'] = unitFanID
					melDevice['thermoID'] = unitThermoID
					melDevice['vaneHozID'] = unitVaneHozID
					melDevice['vaneVerID'] = unitVaneVerID
					melDevice['roomTempID'] = unitRoomTempID
					melDevice['infosID'] = unitInfosID
					melDevices.append(melDevice)
					unitModeID += 7
					unitFanID += 7
					unitThermoID += 7
					unitVaneHozID += 7
					unitVaneVerID += 7
					unitRoomTempID += 7
					unitInfosID += 7
	#Search in floors
			for floor in building["Structure"]["Floors"]:
				for device in floor["Devices"]:
					melDevice = {}
					melBuildingID = device["BuildingID"]
					melDevice['name'] = device["DeviceName"]
					melDevice['id'] = device["DeviceID"]
					melDevice['macaddr'] = device["MacAddress"]
					melDevice['sn'] = device["SerialNumber"]
					melDevice['modeID'] = unitModeID
					melDevice['fanID'] = unitFanID
					melDevice['thermoID'] = unitThermoID
					melDevice['vaneHozID'] = unitVaneHozID
					melDevice['vaneVerID'] = unitVaneVerID
					melDevice['roomTempID'] = unitRoomTempID
					melDevice['infosID'] = unitInfosID
					melDevices.append(melDevice)
					unitModeID += 7
					unitFanID += 7
					unitThermoID += 7
					unitVaneHozID += 7
					unitVaneVerID += 7
					unitRoomTempID += 7
					unitInfosID += 7
				for area in floor["Areas"]:
					for device in area["Devices"]:
						melDevice = {}
						melBuildingID = device["BuildingID"]
						melDevice['name'] = device["DeviceName"]
						melDevice['id'] = device["DeviceID"]
						melDevice['macaddr'] = device["MacAddress"]
						melDevice['sn'] = device["SerialNumber"]
						melDevice['modeID'] = unitModeID
						melDevice['fanID'] = unitFanID
						melDevice['thermoID'] = unitThermoID
						melDevice['vaneHozID'] = unitVaneHozID
						melDevice['vaneVerID'] = unitVaneVerID
						melDevice['roomTempID'] = unitRoomTempID
						melDevice['infosID'] = unitInfosID
						melDevices.append(melDevice)
						unitModeID += 7
						unitFanID += 7
						unitThermoID += 7
						unitVaneHozID += 7
						unitVaneVerID += 7
						unitRoomTempID += 7
						unitInfosID += 7
		return True
 
	def melSetPower(self,melDeviceID,setPower):
		global melKey
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta"
		headers = {'X-MitsContextKey': melKey}
		post_fields = {'Power': setPower, \
						'DeviceID': melDeviceID, \
						'EffectiveFlags': '1', \
						'HasPendingCommand': 'true'}
		request = Request(url,urlencode(post_fields).encode(),headers=headers)
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		Domoticz.Debug("Next update for command power: " + jsonResponse["NextCommunication"])
		return True
 
	def melSetMode(self,melDeviceID,setMode):
		global melKey
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta"
		headers = {'X-MitsContextKey': melKey}
		post_fields = {'Power': "true", \
						'OperationMode': str(setMode), \
						'DeviceID': melDeviceID, \
						'EffectiveFlags': '6', \
						'HasPendingCommand': 'true'}
		request = Request(url,urlencode(post_fields).encode(),headers=headers)
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		Domoticz.Debug("Next update for command mode: " + jsonResponse["NextCommunication"])
		return True
 
	def melSetFan(self,melDeviceID,setFan):
		global melKey
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta"
		headers = {'X-MitsContextKey': melKey}
		post_fields = {'SetFanSpeed': setFan, \
						'DeviceID': melDeviceID, \
						'EffectiveFlags': '8', \
						'HasPendingCommand': 'true'}
		request = Request(url,urlencode(post_fields).encode(),headers=headers)
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		Domoticz.Debug("Next update for command fan: " + jsonResponse["NextCommunication"])
		return True
 
	def melSetTemp(self,melDeviceID,setTemp):
		global melKey
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta"
		headers = {'X-MitsContextKey': melKey}
		post_fields = {'SetTemperature': setTemp, \
						'DeviceID': melDeviceID, \
						'EffectiveFlags': '4', \
						'HasPendingCommand': 'true'}
		request = Request(url,urlencode(post_fields).encode(),headers=headers)
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		Domoticz.Debug("Next update for command temperature: " + jsonResponse["NextCommunication"])
		return True
 
	def melGetStatus(self,melDeviceID):
		global melKey,melBuildingID
		url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/Get?id="+str(melDeviceID)+"&buildingID="+str(melBuildingID)
		headers = {'X-MitsContextKey': melKey}
		request = Request(url,None,headers=headers)
		dataResponse = urlopen(request).read().decode()
		jsonResponse = json.loads(dataResponse)
		return jsonResponse
 
	def stringToBase64(self,s):
		return base64.b64encode(s.encode('utf-8')).decode("utf-8")
 
 
global _plugin
_plugin = BasePlugin()
 
def onStart():
	global _plugin
	_plugin.onStart()
 
def onStop():
	global _plugin
	_plugin.onStop()
 
def onConnect(Status, Description):
	global _plugin
	_plugin.onConnect(Status, Description)
 
def onMessage(Data, Status, Extra):
	global _plugin
	_plugin.onMessage(Data, Status, Extra)
 
def onCommand(Unit, Command, Level, Hue):
	global _plugin
	_plugin.onCommand(Unit, Command, Level, Hue)
 
def onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile):
    global _plugin
    _plugin.onNotification(Name, Subject, Text, Status, Priority, Sound, ImageFile)
 
def onDisconnect():
	global _plugin
	_plugin.onDisconnect()
 
def onHeartbeat():
	global _plugin
	_plugin.onHeartbeat()
 
    # Generic helper functions
def DumpConfigToLog():
	for x in Parameters:
		if Parameters[x] != "":
			Domoticz.Debug( "'" + x + "':'" + str(Parameters[x]) + "'")
	Domoticz.Debug("Device count: " + str(len(Devices)))
	for x in Devices:
		Domoticz.Debug("Device:           " + str(x) + " - " + str(Devices[x]))
		Domoticz.Debug("Device ID:       '" + str(Devices[x].ID) + "'")
		Domoticz.Debug("Device Name:     '" + Devices[x].Name + "'")
		Domoticz.Debug("Device nValue:    " + str(Devices[x].nValue))
		Domoticz.Debug("Device sValue:   '" + Devices[x].sValue + "'")
		Domoticz.Debug("Device LastLevel: " + str(Devices[x].LastLevel))
	return


Put this file in directory Melcloud under DOMOTICZ_DIR/plugins

Configuration

You can add devices by going to hardware.