Re: [Perl] Control Mitsubishi MAC-557IF-E airconditioning
Posted: Monday 21 March 2016 17:05
Do you have some floor or area ?
Can you delete them ?
Can you delete them ?
Open source Home Automation System
https://forum.domoticz.com/
Code: Select all
#!/usr/bin/perl
#Dependency: libwww-perl, libjson-perl
# Original script : gysmo38
# Modifications : bagnico
###################################################
# Release notes
###################################################
# Version 0.5:
# - MELCloud login, password can be define in domoticz using User variables : MEL_login (string) an MEL_pass (string)
# - debug can be define in domoticz using User variables: MEL_debug (int)
# - search units in Areas, Devices and Floors
# Version 0.4:
# - add vane option horizontal
# - Change report to domoticz for informations (MODE | T°C | TIME_NEXT_UPDATE)
# - Change split time (remove .xxx)
# Version 0.3:
# - setDomDeviceMode OK
# - Script works with no Areas
# - add 1 hours for uptime (for french)
# Version 0.2:
# - add 2 hours for uptime time (for french)
# - add mode option
# - add fan option
# - add vane option (only vertical)
# - add settemp option
# Version 0.1: First release (with very dirty code...)
# - switch on / off unit
# - report room temperature
# - report unit temperature set
# - report next unit update
use HTTP::Request::Common qw(POST GET);
use HTTP::Headers;
use LWP::UserAgent;
use JSON;
use Data::Dumper;
#####################################################
# Configuration
#####################################################
my $domIP = "192.168.1.1"; # Domoticz IP
my $domPORT = "8080"; # Domoticz PORT
#Define here or define user variables in domoticz
#MELCLOUD_login(string), MELCLOUD_pass(string) and MELCLOUD_debug(int)
my $Email = "exemple\@exemple.net"; # Email used to login to MELcloud
my $Password = "password"; # Password used lo login to MELcloud
my $debug = 1; # 0 = no debug, 1 = debug
my @devicesInfos; # List of all devices. Add block for new devices
#Device 1
$devicesInfos{"Salle"}{"idx_status"} = "88"; # IDX of status device (type switch)
$devicesInfos{"Salle"}{"idx_temp"} = "90"; # IDX of temperature device (type temp)
$devicesInfos{"Salle"}{"idx_info"} = "92"; # IDX of update time device (type text)
$devicesInfos{"Salle"}{"idx_setTemp"} = "89"; # IDX of set temp device (type set point)
#Device n
#$devicesInfos{"Bib"}{"idx_status"} = "104";
#$devicesInfos{"Bib"}{"idx_temp"} = "97";
#$devicesInfos{"Bib"}{"idx_info"} = "112";
#$devicesInfos{"Bib"}{"idx_setTemp"} = "108";
##########################################################
# Functions
##########################################################
sub debug {
my ($msg) = @_;
if ($debug) {
print $msg."\n";
}
}
sub getConfDomoticz {
$debug = 1;
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=getuservariables";
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$json = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($json);
my @user_variables = @{$decoded->{'result'}};
foreach my $user_variable ( @user_variables ) {
if ($user_variable->{"Name"} eq "MEL_login") {
$Email = $user_variable->{"Value"};
}
elsif ($user_variable->{"Name"} eq "MEL_pass") {
$Password = $user_variable->{"Value"};
}
elsif ($user_variable->{"Name"} eq "MEL_debug") {
$debug = $user_variable->{"Value"};
}
}
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
# $result = $1 if /(?:Status\"\ :)+(.*?),/s;
# debug("receive from domoticz: ".$decoded);
return $result;
}
}
sub time_offset {
my ($time,$offset) = @_;
@split_time = split(/:/,$time);
# debug("Time: ".$split_time[0]);
if ($split_time[0] <= 22) {
$split_time[0] = $split_time[0] + 1;
}
elsif ($split_time[0] == 23) {
$split_time[0] = 00;
}
$result = join(":",$split_time[0],$split_time[1],$split_time[2]);
@timeok = split(/\./,$result);
return $timeok[0];
}
sub getDOMDeviceStatus {
my ($idx) = @_;
my $url = "http://$domIP:$domPORT/json.htm?type=devices&rid=".$idx;
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
$result = $1 if /(?:Status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
sub login {
#Parameters
my ($Email,$Password) = @_;
#Variables
my $AppVersion = "1.9.3.0";
my $Language = "7";
my $CaptchaChallenge = "";
my $CaptchaResponse = "";
my $Persist = "true";
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Login/ClientLogin";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
# file.cgi should just return the data sent for this test
# These seem to be like <input type=text name=A value=$A > off a form...
my $req = POST $url, [
AppVersion => "$AppVersion",
CaptchaChallenge => "$CaptchaChallenge",
CaptchaResponse => "$CaptchaResponse",
Email => "$Email",
Language => "$Language",
Password => "$Password",
Persist => "$Persist"
];
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
elsif(/\"ErrorId\":1/ig) {
return "Bad password\n";
}
elsif(/\"ErrorId\":null/ig) {
$result = $1 if /(?:ContextKey\":\")+(.*?)\"/s;
debug ("context ID: ".$result);
return $result;
}
else {
return "Unknow error";
}
}
sub getMELBuildingID {
#Parameters
my ($ContextKey,$devicename) = @_;
#Variables
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $ContextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($_);
my $result = "0";
foreach my $building (@$decoded) {
@devices = @{$building->{'Structure'}{'Floors'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'BuildingID'};
}
}
debug("BuildingID: ".Dumper($result));
}
foreach my $building (@$decoded) {
@devices = @{$building->{'Structure'}{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'BuildingID'};
}
}
debug("BuildingID: ".Dumper($result));
}
foreach my $building (@$decoded) {
@build = @{$building->{'Structure'}{'Areas'}};
foreach my $area (@build) {
@devices = @{$area->{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'BuildingID'};
}
}
}
}
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
# debug("Building ID: ".Dumper($decoded));
return "$result";
}
}
sub getMELDeviceID {
#Parameters
my ($ContextKey,$devicename) = @_;
#Variables
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $ContextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($_);
my $result = "0";
foreach my $building (@$decoded) {
@devices = @{$building->{'Structure'}{'Floors'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'DeviceID'};
}
}
debug("DeviceID: ".Dumper($result));
}
foreach my $building (@$decoded) {
@devices = @{$building->{'Structure'}{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'DeviceID'};
}
}
debug("DeviceID: ".Dumper($result));
}
foreach my $building (@$decoded) {
@build = @{$building->{'Structure'}{'Areas'}};
foreach my $area (@build) {
@devices = @{$area->{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'DeviceID'};
}
}
}
}
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
# debug("Device ID: ".Dumper($decoded));
return "$result";
}
}
sub listDevices {
#Parameters
my ($ContextKey) = @_;
#Variables
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $ContextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
$result = $_;
debug("list devices: ".$result);
return "$result";
}
}
sub getAirConInfos {
#Parameters
my ($contextKey,$deviceID,$buildingID) = @_;
debug("getairconinfos : ".$contextKey,$deviceID,$buildingID);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/Get?id=' . $deviceID . '&buildingID=' . $buildingID;
# debug("device status : ". $url);
#return $url;
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $contextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$json = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($json);
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
# debug("device status : ". $decoded);
return $decoded;
}
}
sub setDomDeviceStatus {
#Parameters
my ($idDomDevice,$deviceInfos) = @_;
#Variables
$domStatus = getDOMDeviceStatus($idDomDevice);
if ($deviceInfos->{'Power'} =~ /true/ && $domStatus =~ /"Off"/) {
$switchcmd = "On";
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=switchlight&idx=".$idDomDevice."&switchcmd=".$switchcmd;
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
$result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
elsif ($deviceInfos->{'Power'} =~ /false/ && $domStatus =~ /"On"/) {
$switchcmd = "Off";
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=switchlight&idx=".$idDomDevice."&switchcmd=".$switchcmd;
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
$result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
else {
debug("send to domoticz: nothing to send");
}
}
sub setDomDeviceTempRoom {
#Parameters
my ($idDomDevice,$deviceInfos) = @_;
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=udevice&idx=".$idDomDevice."&nvalue=0&svalue=".$deviceInfos->{'RoomTemperature'};
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
$result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
sub setDomDeviceInfo {
#Parameters
my ($idDomDevice,$deviceInfos) = @_;
my $mode = $deviceInfos->{'OperationMode'};
@timenextupdate = split(/T/,$deviceInfos->{'NextCommunication'});
if ( $mode == 1) {
$modeclim = 'MODE CHAUD';
}
elsif ( $mode == 2) {
$modeclim = 'MODE SECHAGE';
}
elsif ( $mode == 3) {
$modeclim = 'MODE FROID';
}
elsif ( $mode == 7) {
$modeclim = 'MODE VENTILATION';
}
elsif ( $mode == 8) {
$modeclim = 'MODE AUTO';
}
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=udevice&idx=".$idDomDevice."&nvalue=0&svalue=".$modeclim."%20|%20 ".$deviceInfos->{'SetTemperature'}."%20°C%20|%20".time_offset($timenextupdate[1],2);
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
return "Server returned error: $err\n";
}
else {
$result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
sub setMELDevicePower {
#Parameters
my ($contextKey,$status,$deviceInfos,$idx) = @_;
if($status =~ /on/ ) {
$deviceInfos->{'Power'} = "true";
}
elsif($status =~ /off/ ) {
$deviceInfos->{'Power'} = "false";
}
$deviceInfos->{'EffectiveFlags'} = "1";
$deviceInfos->{'HasPendingCommand'} = "true";
$json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
#return $url;
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
debug($_);
if (/Illegal Operation/ig || $err != 200) {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDevicePower : OK");
}
}
sub setMELDeviceFan {
#Parameters
my ($contextKey,$temp,$deviceInfos,$idx) = @_;
$deviceInfos->{'SetFanSpeed'} = $temp;
$deviceInfos->{'EffectiveFlags'} = "8";
$deviceInfos->{'HasPendingCommand'} = "true";
$json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceFan : OK");
}
}
sub setMELDeviceMode {
#Parameters
my ($contextKey,$mode,$deviceInfos,$idx) = @_;
# Mode value : 1 warm, 2 dry, 3 cool, 7 vent, 8 auto
if ($mode =~ warm) {
$deviceInfos->{'OperationMode'} = 1;
}
elsif ($mode =~ dry) {
$deviceInfos->{'OperationMode'} = 2;
}
elsif ($mode =~ cool) {
$deviceInfos->{'OperationMode'} = 3;
}
elsif ($mode =~ vent) {
$deviceInfos->{'OperationMode'} = 7;
}
elsif ($mode =~ auto) {
$deviceInfos->{'OperationMode'} = 8;
}
$deviceInfos->{'EffectiveFlags'} = "6";
$deviceInfos->{'HasPendingCommand'} = "true";
$json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceMode : OK");
}
}
sub setMELDeviceVaneVertical {
#Parameters
my ($contextKey,$vane,$deviceInfos,$idx) = @_;
$deviceInfos->{'VaneVertical'} = $vane;
$deviceInfos->{'EffectiveFlags'} = "16";
$deviceInfos->{'HasPendingCommand'} = "true";
$json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceVaneVertical : OK");
}
}
sub setMELDeviceVaneHorizontal {
#Parameters
my ($contextKey,$vane,$deviceInfos,$idx) = @_;
$deviceInfos->{'VaneHorizontal'} = $vane;
$deviceInfos->{'EffectiveFlags'} = "16";
$deviceInfos->{'HasPendingCommand'} = "true";
$json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceVaneHorizontal : OK");
}
}
sub setMELDeviceTemp {
#Parameters
my ($contextKey,$temp,$deviceInfos,$idx) = @_;
$deviceInfos->{'SetTemperature'} = $temp;
$deviceInfos->{'EffectiveFlags'} = "4";
$deviceInfos->{'HasPendingCommand'} = "true";
$json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if (/Illegal Operation/ig || $err != 200) {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceTemp : OK");
}
}
sub init_mel {
#Parameters
my ($search_name) = @_;
$contextID = login($Email,$Password);
foreach my $name (keys %devicesInfos) {
if ( $name =~ $search_name ) {
$buildingID = getMELBuildingID($contextID,$name);
$deviceID = getMELDeviceID($contextID,$name);
}
}
}
#####################################################
# Main program
#####################################################
#Get conf from Domoticz
getConfDomoticz();
#####################################################
# Arguments
#####################################################
if ($ARGV[0] =~ /report/) {
$contextID = login($Email,$Password);
foreach my $name (keys %devicesInfos) {
$buildingID = getMELBuildingID($contextID,$name);
$deviceID = getMELDeviceID($contextID,$name);
debug("############################");
debug("# Reporting device: " . $name ." #");
debug("############################");
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setDomDeviceTempRoom($devicesInfos{$name}{"idx_temp"},$infosAirCon);
setDomDeviceStatus($devicesInfos{$name}{"idx_status"},$infosAirCon);
setDomDeviceInfo($devicesInfos{$name}{"idx_info"},$infosAirCon);
}
}
elsif ($ARGV[0] =~ /test/) {
init_mel($ARGV[1]);
debug("Send command to building:" . $buildingID);
debug("Send command to device:" . $deviceID);
}
elsif ($ARGV[0] =~ /temp/ && exists $devicesInfos{$ARGV[2]}{'idx_status'}) {
init_mel($ARGV[2]);
@temp = split(/:/,$ARGV[1]);
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceTemp($contextID,$temp[0],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
elsif ($ARGV[0] =~ /fan/ && exists $devicesInfos{$ARGV[2]}{'idx_status'}) {
init_mel($ARGV[2]);
debug("Send commande to device:" . $buildingID);
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceFan($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
elsif ($ARGV[0] =~ /power/ && exists $devicesInfos{$ARGV[2]}{'idx_status'}) {
init_mel($ARGV[2]);
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setMELDevicePower($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
elsif ($ARGV[0] =~ /mode/ && exists $devicesInfos{$ARGV[2]}{'idx_status'}) {
init_mel($ARGV[2]);
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceMode($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
elsif ($ARGV[0] =~ /vanevertical/ && exists $devicesInfos{$ARGV[2]}{'idx_status'}) {
init_mel($ARGV[2]);
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceVaneVertical($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
elsif ($ARGV[0] =~ /vanehorizontal/ && exists $devicesInfos{$ARGV[2]}{'idx_status'}) {
init_mel($ARGV[2]);
$infosAirCon = getAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceVaneHorizontal($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
elsif ($ARGV[0] =~ /help/) {
print "-------------------------- MELCLOUD PERL FOR DOMOTICZ v0.5 --------------------------\n";
print "report: send status of devices to domoticz. Use it for crontab\n";
print "power on/off DEVICENAME: power on or off a device.\n";
print "mode modename DEVICENAME: choose mode warm,dry,cool,vent or auto\n";
print "temp T° DEVICENAME: set temperature device. \n";
print "fan FAN_SPEED DEVICENAME: set fan speed of the device. \n";
print "vanevertical VANE_POS DEVICENAME: set van position to 1 - 5, 0 to auto and 7 to move . \n";
print "vanehorizontal VANE_POS DEVICENAME: set van position to 1 - 5, 0 to auto and 12 to move . \n";
print "more to come...\n";
}
else {
print "Nothing to do. Type help for help ;)\n";
}
Code: Select all
$deviceInfos->{'EffectiveFlags'} = "16";
Code: Select all
$deviceInfos->{'EffectiveFlags'} = "256";
Hello,gysmo38 wrote:Ok can you send me the line code 93?
Because the line number depend the number of device that you define.
Do you use auth for domoticz? Do you use SSL(https)?
Because now, it only work with http and no auth.
Code: Select all
"Raspberry Pi pi @: ~ $ ./melcloud.pl report
unexpected end of string while parsing JSON string, character at offset 5 (before "uccess: false, Error ...") at ./melcloud.pl line 230 "
Code: Select all
my $decoded = JSON->new->utf8(0)->decode($_);
Code: Select all
#!/usr/bin/perl
#####################################################
# Configuration
#####################################################
$domIP = "X.X.X.X"; # Domoticz IP
$domPORT = "8080"; # Domoticz PORT
#Define here or define user variables in domoticz
#MELCLOUD_login(string), MELCLOUD_pass(string) and MELCLOUD_debug(int)
$Email = "EMAIL"; # Email used to login to MELcloud
$Password = "PASSWORD"; # Password used lo login to MELcloud
$debug = 1; # 0 = no debug, 1 = debug
#Define here or define virtuals devices like this
# Power unit: type: switch; name: MEL Power NAMEDEVICE
# Mode unit: type: selector; name: MEL Mode NAMEDEVICE
# -> Check hide off level
# -> Level 10 : Warm Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl mode warm NAMEDEVICE
# -> Level 20 : Cool Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl mode cool NAMEDEVICE
# -> Level 30 : Vent Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl mode vent NAMEDEVICE
# -> Level 40 : Dry Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl mode dry NAMEDEVICE
# -> Level 50 : Auto Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl mode auto NAMEDEVICE
# Fan speed unit: type: selector; name: MEL Fan NAMEDEVICE
# -> Check hide off level
# -> Level 10 : Level 1 Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl fan 1 NAMEDEVICE
# -> Level 20 : Level 2 Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl fan 2 NAMEDEVICE
# -> Level 30 : Level 3 Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl fan 3 NAMEDEVICE
# -> Level 40 : Level 4 Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl fan 255 NAMEDEVICE
# -> Level 50 : Silence Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl fan 0 NAMEDEVICE
# -> Level 60 : Auto Script Commande: script:///home/pi/domoticz/scripts/melcloud.pl fan auto NAMEDEVICE
# Temp unit report: type: name: MEL Temp NAMEDEVICE
# Set temp unit: type: name: MEL Therm NAMEDEVICE
# Infos unit: type: text name: MEL Infos NAMEDEVICE
#MELCLOUD_login(string), MELCLOUD_pass(string) and MELCLOUD_debug(int)
@devicesInfos; # List of all devices. Add block for new devices
#Device 1
$devicesInfos{"Salle"}{"idx_mode"} = "151"; # IDX of status device (type selector Off=0, Hot=10, Cold=20, Vent=30, Dry=40, Auto=50)
$devicesInfos{"Salle"}{"idx_temp"} = "90"; # IDX of temperature device (type temp)
$devicesInfos{"Salle"}{"idx_info"} = "92"; # IDX of update time device (type text)
$devicesInfos{"Salle"}{"idx_setTemp"} = "89"; # IDX of set temp device (type set point)
#Device 2
$devicesInfos{"Bib"}{"idx_status"} = "104";
$devicesInfos{"Bib"}{"idx_temp"} = "97";
$devicesInfos{"Bib"}{"idx_info"} = "112";
$devicesInfos{"Bib"}{"idx_setTemp"} = "108";
#Device 3
$devicesInfos{"Maxime"}{"idx_status"} = "103";
$devicesInfos{"Maxime"}{"idx_temp"} = "96";
$devicesInfos{"Maxime"}{"idx_info"} = "111";
$devicesInfos{"Maxime"}{"idx_setTemp"} = "107";
#Device 4
$devicesInfos{"Simon"}{"idx_status"} = "102";
$devicesInfos{"Simon"}{"idx_temp"} = "95";
$devicesInfos{"Simon"}{"idx_info"} = "110";
$devicesInfos{"Simon"}{"idx_setTemp"} = "106";
#Device 5
$devicesInfos{"Parents"}{"idx_status"} = "101";
$devicesInfos{"Parents"}{"idx_temp"} = "94";
$devicesInfos{"Parents"}{"idx_info"} = "109";
$devicesInfos{"Parents"}{"idx_setTemp"} = "105";
Code: Select all
#!/usr/bin/perl
#Dependency: libwww-perl, libjson-perl
# Original script : gysmo38
# Modifications : bagnico
###################################################
# Release notes
###################################################
# Version 0.6:
# - seperate configuration in config.pl (more easy to help people)
# - add use strict and use warnings
# - clean code to have no errors with strict and warnings
# - for using selector swictch in domoticz, add power on command when change mode
# Version 0.5:
# - MELCloud login, password can be define in domoticz using User variables : MEL_login (string) an MEL_pass (string)
# - debug can be define in domoticz using User variables: MEL_debug (int)
# - search units in Areas, Devices and Floors
# Version 0.4:
# - add vane option horizontal
# - Change report to domoticz for informations (MODE | T°C | TIME_NEXT_UPDATE)
# - Change split time (remove .xxx)
# Version 0.3:
# - setDomDeviceMode OK
# - Script works with no Areas
# - add 1 hours for uptime (for french)
# Version 0.2:
# - add 2 hours for uptime time (for french)
# - add mode option
# - add fan option
# - add vane option (only vertical)
# - add settemp option
# Version 0.1: First release (with very dirty code...)
# - switch on / off unit
# - report room temperature
# - report unit temperature set
# - report next unit update
use strict;
use warnings;
use HTTP::Request::Common qw(POST GET);
use HTTP::Headers;
use LWP::UserAgent;
use JSON;
use Data::Dumper;
##########################################################
# Include config variables
##########################################################
require 'config.pl';
our $domIP;
our $domPORT;
our $Email;
our $Password;
our $debug;
our @devicesInfos;
our %devicesInfos;
##########################################################
# Variables
##########################################################
my $version = "0.6";
my $contextID;
my $infosAirCon;
my $buildingID;
my $deviceID;
my @temp;
##########################################################
# Functions
##########################################################
sub debug {
my ($msg) = @_;
if ($debug) {
print $msg."\n";
}
}
sub domSendJSON {
my ($params) = @_;
my $result;
my $url = "http://$domIP:$domPORT/json.htm?$params";
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
my $json = $res->decoded_content;
if ($err =~ /200 OK/) {
return $json;
}
else {
print "Domoticz connection fail. Check configuration.\n";
print "Error message : $err\n";
exit;
}
}
sub melSendJSON {
my ($contextKey,$url) = @_;
my $result;
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $contextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
my $json = $res->decoded_content;
if ($err =~ /200 OK/) {
return $json;
}
else {
print "MEL connection fail. Check configuration.\n";
print "Error message : $err\n";
exit;
}
}
sub getConfDomoticz {
my $result;
my $json = domSendJSON("type=command¶m=getuservariables");
my $decoded = JSON->new->utf8(0)->decode($json);
my @user_variables = @{$decoded->{'result'}};
foreach my $user_variable ( @user_variables ) {
if ($user_variable->{"Name"} eq "MEL_login") {
$Email = $user_variable->{"Value"};
}
elsif ($user_variable->{"Name"} eq "MEL_pass") {
$Password = $user_variable->{"Value"};
}
elsif ($user_variable->{"Name"} eq "MEL_debug") {
$debug = $user_variable->{"Value"};
}
}
return $result;
}
sub time_offset {
my ($time,$offset) = @_;
my $result;
my @split_time = split(/:/,$time);
my @timeok;
# debug("Time: ".$split_time[0]);
if ($split_time[0] <= 22) {
$split_time[0] = $split_time[0] + 1;
}
elsif ($split_time[0] == 23) {
$split_time[0] = 00;
}
$result = join(":",$split_time[0],$split_time[1],$split_time[2]);
@timeok = split(/\./,$result);
return $timeok[0];
}
sub getDOMDeviceStatus {
my ($idx) = @_;
my $result;
my $url = "http://$domIP:$domPORT/json.htm?type=devices&rid=".$idx;
my $ua = LWP::UserAgent->new();
my $req;
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
$result = $1 if /(?:Status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
sub login {
#Parameters
my ($Email,$Password) = @_;
#Variables
my $result;
my $AppVersion = "1.9.3.0";
my $Language = "7";
my $CaptchaChallenge = "";
my $CaptchaResponse = "";
my $Persist = "true";
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Login/ClientLogin";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
# file.cgi should just return the data sent for this test
# These seem to be like <input type=text name=A value=$A > off a form...
my $req = POST $url, [
AppVersion => "$AppVersion",
CaptchaChallenge => "$CaptchaChallenge",
CaptchaResponse => "$CaptchaResponse",
Email => "$Email",
Language => "$Language",
Password => "$Password",
Persist => "$Persist"
];
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
elsif(/\"ErrorId\":1/ig) {
return "Bad password\n";
}
elsif(/\"ErrorId\":null/ig) {
$result = $1 if /(?:ContextKey\":\")+(.*?)\"/s;
return $result;
}
else {
return "Unknow error";
}
}
sub getMELBuildingID {
#Parameters
my ($ContextKey,$devicename) = @_;
#Variables
my @devices;
my $req;
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
$req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $ContextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($_);
my $result = "0";
foreach my $building (@$decoded) {
@devices = @{$building->{'Structure'}{'Floors'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'BuildingID'};
}
}
# debug("BuildingID: ".Dumper($result));
}
foreach my $building (@$decoded) {
@devices = @{$building->{'Structure'}{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'BuildingID'};
}
}
#debug("BuildingID: ".Dumper($result));
}
foreach my $building (@$decoded) {
my @build = @{$building->{'Structure'}{'Areas'}};
foreach my $area (@build) {
@devices = @{$area->{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'BuildingID'};
}
}
}
}
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
# debug("Building ID: ".Dumper($decoded));
return "$result";
}
}
sub getMELDeviceID {
#Parameters
my ($ContextKey,$devicename) = @_;
#Variables
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $ContextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($_);
my $result = "0";
foreach my $building (@$decoded) {
my @devices = @{$building->{'Structure'}{'Floors'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'DeviceID'};
}
}
# debug("DeviceID: ".Dumper($result));
}
foreach my $building (@$decoded) {
my @devices = @{$building->{'Structure'}{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'DeviceID'};
}
}
# debug("DeviceID: ".Dumper($result));
}
foreach my $building (@$decoded) {
my @build = @{$building->{'Structure'}{'Areas'}};
foreach my $area (@build) {
my @devices = @{$area->{'Devices'}};
foreach my $device (@devices) {
if ( $device->{'DeviceName'} =~ $devicename) {
$result = $device->{'DeviceID'};
}
}
}
}
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
# debug("Device ID: ".Dumper($decoded));
return "$result";
}
}
sub listDevices {
#Parameters
my ($ContextKey) = @_;
#Variables
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/User/ListDevices";
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
$req->header("X-MitsContextKey" => $ContextKey);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
my $result = $_;
debug("list devices: ".$result);
return "$result";
}
}
# Get ALL Devices IDX to make update
sub getDOMDevicesIDX {
$debug = 1;
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=getuservariables";
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
my $json = $res->decoded_content;
my $decoded = JSON->new->utf8(0)->decode($json);
my @user_variables = @{$decoded->{'result'}};
foreach my $user_variable ( @user_variables ) {
if ($user_variable->{"Name"} eq "MEL_login") {
$Email = $user_variable->{"Value"};
}
elsif ($user_variable->{"Name"} eq "MEL_pass") {
$Password = $user_variable->{"Value"};
}
elsif ($user_variable->{"Name"} eq "MEL_debug") {
$debug = $user_variable->{"Value"};
}
}
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
# $result = $1 if /(?:Status\"\ :)+(.*?),/s;
# debug("receive from domoticz: ".$decoded);
return my $result;
}
}
sub melGetAirConInfos {
#Parameters
my ($contextKey,$deviceID,$buildingID) = @_;
my $url = "https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/Get?id=$deviceID&buildingID=$buildingID";
my $json = melSendJSON($contextKey,$url);
my $decoded = JSON->new->utf8(0)->decode($json);
#debug ("Infos AC: $decoded->{'RoomTemperature'}");
#debug("device status : ". $decoded);
return $decoded;
}
sub setDomDeviceStatus {
#Parameters
my ($idDomDevice,$deviceInfos) = @_;
#Variables
my $domStatus = getDOMDeviceStatus($idDomDevice);
if ($deviceInfos->{'Power'} =~ /true/ && $domStatus =~ /"Off"/) {
my $switchcmd = "On";
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=switchlight&idx=".$idDomDevice."&switchcmd=".$switchcmd;
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
my $result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
elsif ($deviceInfos->{'Power'} =~ /false/ && my $domStatus =~ /"On"/) {
my $switchcmd = "Off";
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=switchlight&idx=".$idDomDevice."&switchcmd=".$switchcmd;
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
my $result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
else {
debug("send to domoticz: nothing to send");
}
}
sub setDomDeviceTempRoom {
#Parameters
my ($idDomDevice,$deviceInfos) = @_;
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=udevice&idx=".$idDomDevice."&nvalue=0&svalue=".$deviceInfos->{'RoomTemperature'};
debug("send to domoticz: ".$url);
my $result = domSendJSON("type=command¶m=udevice&idx=$idDomDevice&nvalue=0&svalue=$deviceInfos->{'RoomTemperature'}") if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
sub setDomDeviceInfo {
#Parameters
my ($idDomDevice,$deviceInfos) = @_;
my $mode = $deviceInfos->{'OperationMode'};
my @timenextupdate = split(/T/,$deviceInfos->{'NextCommunication'});
my $modeclim;
print "MODE: $mode\n";
if ( $mode eq "1") {
$modeclim = 'MODE CHAUD';
}
elsif ( $mode eq "2") {
$modeclim = 'MODE SECHAGE';
}
elsif ( $mode == 3) {
$modeclim = 'MODE FROID';
}
elsif ( $mode == 7) {
$modeclim = 'MODE VENTILATION';
}
elsif ( $mode == 8) {
$modeclim = 'MODE AUTO';
}
my $url = "http://$domIP:$domPORT/json.htm?type=command¶m=udevice&idx=".$idDomDevice."&nvalue=0&svalue=".$modeclim."%20|%20 ".$deviceInfos->{'SetTemperature'}."%20°C%20|%20".time_offset($timenextupdate[1],2);
debug("send to domoticz: ".$url);
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(GET => $url);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
return "Server returned error: $err\n";
}
else {
my $result = $1 if /(?:status\"\ :)+(.*?),/s;
debug("receive from domoticz: ".$result);
return $result;
}
}
sub setMELDevicePower {
#Parameters
my ($contextKey,$status,$deviceInfos,$idx) = @_;
if($status =~ /on/ ) {
$deviceInfos->{'Power'} = "true";
}
elsif($status =~ /off/ ) {
$deviceInfos->{'Power'} = "false";
}
$deviceInfos->{'EffectiveFlags'} = "1";
$deviceInfos->{'HasPendingCommand'} = "true";
my $json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
#return $url;
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
my $result = $res->decoded_content;
# debug($result);
if ($err =~ "Illegal Operation") {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDevicePower : OK");
}
}
sub setMELDeviceFan {
#Parameters
my ($contextKey,$temp,$deviceInfos,$idx) = @_;
$deviceInfos->{'SetFanSpeed'} = $temp;
$deviceInfos->{'EffectiveFlags'} = "8";
$deviceInfos->{'HasPendingCommand'} = "true";
my $json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceFan : OK");
}
}
sub setMELDeviceMode {
#Parameters
my ($contextKey,$mode,$deviceInfos,$idx) = @_;
# Mode value : 1 warm, 2 dry, 3 cool, 7 vent, 8 auto
if ($mode =~ 'warm') {
$deviceInfos->{'OperationMode'} = 1;
}
elsif ($mode =~ 'dry') {
$deviceInfos->{'OperationMode'} = 2;
}
elsif ($mode =~ 'cool') {
$deviceInfos->{'OperationMode'} = 3;
}
elsif ($mode =~ 'vent') {
$deviceInfos->{'OperationMode'} = 7;
}
elsif ($mode =~ 'auto') {
$deviceInfos->{'OperationMode'} = 8;
}
$deviceInfos->{'EffectiveFlags'} = "6";
$deviceInfos->{'HasPendingCommand'} = "true";
my $json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceMode : OK");
}
}
sub setMELDeviceVaneVertical {
#Parameters
my ($contextKey,$vane,$deviceInfos,$idx) = @_;
$deviceInfos->{'VaneVertical'} = $vane;
$deviceInfos->{'EffectiveFlags'} = "16";
$deviceInfos->{'HasPendingCommand'} = "true";
my $json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceVaneVertical : OK");
}
}
sub setMELDeviceVaneHorizontal {
#Parameters
my ($contextKey,$vane,$deviceInfos,$idx) = @_;
$deviceInfos->{'VaneHorizontal'} = $vane;
$deviceInfos->{'EffectiveFlags'} = "16";
$deviceInfos->{'HasPendingCommand'} = "true";
my $json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceVaneHorizontal : OK");
}
}
sub setMELDeviceTemp {
#Parameters
my ($contextKey,$temp,$deviceInfos,$idx) = @_;
$deviceInfos->{'SetTemperature'} = $temp;
$deviceInfos->{'EffectiveFlags'} = "4";
$deviceInfos->{'HasPendingCommand'} = "true";
my $json_device = JSON->new->utf8->encode($deviceInfos);
#Variables
my $url = 'https://app.melcloud.com/Mitsubishi.Wifi.Client/Device/SetAta';
# set up the stuff
my $ua = LWP::UserAgent->new();
# Set our own user-agent string!
$ua->agent("Domoticz Gysmo");
require HTTP::Request;
my $req = HTTP::Request->new(POST => $url);
$req->header("X-MitsContextKey" => $contextKey);
$req->header('content-type' => 'application/json');
$req->content($json_device);
# Fire the cannon now !
my $res = $ua->request($req);
# Get the error back from the server if any
my $err = $res->status_line;
# Get server body text, $_ used in regexp on next line
$_ = $res->decoded_content;
if ($err =~ "Illegal Operation") {
print "Server returned error: $err\n";
}
else {
debug("Update setMELDeviceTemp : OK");
}
}
sub init_mel {
#Parameters
my ($search_name) = @_;
$contextID = login($Email,$Password);
foreach my $name (keys %devicesInfos) {
if ( $name =~ $search_name ) {
$buildingID = getMELBuildingID($contextID,$name);
$deviceID = getMELDeviceID($contextID,$name);
}
}
}
#####################################################
# Main program
#####################################################
#####################################################
# Arguments
#####################################################
if ( !defined($ARGV[0]) ) {
print "Nothing to do. Type help for help ;)\n";
}
elsif ($ARGV[0] =~ /report/) {
#Get conf from Domoticz
getConfDomoticz();
$contextID = login($Email,$Password);
foreach my $name (keys %devicesInfos) {
$buildingID = getMELBuildingID($contextID,$name);
$deviceID = getMELDeviceID($contextID,$name);
debug("############################");
debug("# Reporting device: " . $name ." #");
debug("############################");
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setDomDeviceTempRoom($devicesInfos{$name}{'idx_temp'},$infosAirCon);
setDomDeviceStatus($devicesInfos{$name}{'idx_status'},$infosAirCon);
setDomDeviceInfo($devicesInfos{$name}{'idx_info'},$infosAirCon);
}
}
elsif ($ARGV[0] =~ /check/) {
#Get conf from Domoticz
getConfDomoticz();
$contextID = login($Email,$Password);
print("############################\n");
print("# Check configuration: #\n");
print("############################\n");
print("Connection to domoticz");
print(" [OK]\n");
print("Configuration MEL Cloud");
print(" [DOMOTICZ]\n");
print("Connection to MEL Cloud");
print(" [OK]\n");
}
elsif ($ARGV[0] =~ /test/) {
print "TEST: $devicesInfos{'Salle'}{'idx_temp'}\n";
}
elsif ($ARGV[0] =~ /temp/) {
#Get conf from Domoticz
getConfDomoticz();
if (!defined($ARGV[1]) || !defined($ARGV[2])) {
print "use temp and device name\n";
}
else {
init_mel($ARGV[2]);
@temp = split(/:/,$ARGV[1]);
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceTemp($contextID,$temp[0],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
}
elsif ($ARGV[0] =~ /fan/) {
#Get conf from Domoticz
getConfDomoticz();
if (!defined($ARGV[1]) || !defined($ARGV[2])) {
print "use fan and device name\n";
}
else {
init_mel($ARGV[2]);
debug("Send commande to device:" . $buildingID);
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceFan($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
}
elsif ($ARGV[0] =~ /power/) {
#Get conf from Domoticz
getConfDomoticz();
if (!defined($ARGV[1]) || !defined($ARGV[2])) {
print "use on or off and device name\n";
}
else {
init_mel($ARGV[2]);
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setMELDevicePower($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
}
elsif ($ARGV[0] =~ /mode/) {
#Get conf from Domoticz
getConfDomoticz();
if (!defined($ARGV[1]) || !defined($ARGV[2])) {
print "use cool,warm,vent and device name\n";
}
else {
init_mel($ARGV[2]);
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceMode($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
setMELDevicePower($contextID,'on',$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
}
elsif ($ARGV[0] =~ /vanevertical/) {
#Get conf from Domoticz
getConfDomoticz();
if (!defined($ARGV[1]) || !defined($ARGV[2])) {
print "use vanevertical and device name\n";
}
else {
init_mel($ARGV[2]);
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceVaneVertical($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
}
elsif ($ARGV[0] =~ /vanehorizontal/) {
if (!defined($ARGV[1]) || !defined($ARGV[2])) {
print "use vanehorizontal and device name\n";
}
else {
init_mel($ARGV[2]);
$infosAirCon = melGetAirConInfos($contextID,$deviceID,$buildingID);
setMELDeviceVaneHorizontal($contextID,$ARGV[1],$infosAirCon,$devicesInfos{$ARGV[2]}{'idx_update'});
}
}
elsif ($ARGV[0] =~ /help/) {
print "-------------------------- MELCLOUD PERL FOR DOMOTICZ v$version --------------------------\n";
print "report: send status of devices to domoticz. Use it for crontab\n";
print "power on/off DEVICENAME: power on or off a device.\n";
print "mode modename DEVICENAME: choose mode warm,dry,cool,vent or auto\n";
print "temp T° DEVICENAME: set temperature device. \n";
print "fan FAN_SPEED DEVICENAME: set fan speed of the device. \n";
print "vanevertical VANE_POS DEVICENAME: set van position to 1 - 5, 0 to auto and 7 to move . \n";
print "vanehorizontal VANE_POS DEVICENAME: set van position to 1 - 5, 0 to auto and 12 to move . \n";
print "conf: domoticz user variables conf\n";
print "check: check config\n";
print "more to come...\n";
}
else {
print "Wrong arguments. Use help\n";
}