Merge PR #546: New plugin - Daikin Airco
This commit is contained in:
commit
7376ec795e
16
daikinairco/README.md
Normal file
16
daikinairco/README.md
Normal file
@ -0,0 +1,16 @@
|
||||
# Daikin Airco
|
||||
|
||||
This plugin allows discovery and simple control via Nymea of Daikin airconditioning devices.
|
||||
|
||||
## Supported Things
|
||||
|
||||
* Devices with the Daikin Residential Controller
|
||||
|
||||
## Requirements
|
||||
|
||||
* nymea and the airconditioning device must be in the same local area network.
|
||||
* The package "nymea-plugin-daikinairco" must be installed.
|
||||
|
||||
## More
|
||||
|
||||
[Daikin Residential Controller](https://www.daikin.eu/en_us/product-group/control-systems/daikin-online-controller.html)
|
||||
BIN
daikinairco/daikin.jpg
Normal file
BIN
daikinairco/daikin.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 44 KiB |
139
daikinairco/integrationplugindaikinairco.json
Normal file
139
daikinairco/integrationplugindaikinairco.json
Normal file
@ -0,0 +1,139 @@
|
||||
{
|
||||
"displayName": "Daikin Airco",
|
||||
"name": "Daikinairco",
|
||||
"id": "b5cf475e-707d-46a5-9684-296fb1a14886",
|
||||
"vendors": [
|
||||
{
|
||||
"id": "88f6421c-cc7b-4006-b077-421fc384939c",
|
||||
"displayName": "Daikin",
|
||||
"name": "Daikin",
|
||||
"thingClasses": [
|
||||
{
|
||||
"id": "e6d0bfe6-5923-4c29-840d-ef8b0a17fad9",
|
||||
"name": "airco",
|
||||
"displayName": "Daikin Airco",
|
||||
"createMethods": ["discovery"],
|
||||
"interfaces": ["power", "thermostat", "temperaturesensor", "wirelessconnectable"],
|
||||
"paramTypes": [
|
||||
{
|
||||
"id": "758cad5c-994a-4136-b83d-80fe2f07346c",
|
||||
"name": "deviceId",
|
||||
"displayName": "Device ID",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
},
|
||||
{
|
||||
"id": "1fefe7df-ef8e-4434-bb51-0c521553f750",
|
||||
"name": "deviceName",
|
||||
"displayName": "Device name",
|
||||
"type" : "QString",
|
||||
"readOnly": true
|
||||
}
|
||||
],
|
||||
"settingsTypes": [
|
||||
|
||||
],
|
||||
"stateTypes": [
|
||||
{
|
||||
"id": "71c5b083-6c95-44f0-b54c-b98f0ac459d8",
|
||||
"name": "connected",
|
||||
"displayName": "Connected",
|
||||
"displayNameEvent": "Connected changed",
|
||||
"defaultValue": false,
|
||||
"type": "bool",
|
||||
"cached": false
|
||||
},
|
||||
{
|
||||
"displayName": "Power",
|
||||
"id": "6bb42aa0-2280-408d-89b5-400410abdd73",
|
||||
"name": "power",
|
||||
"displayNameEvent": "Power changed",
|
||||
"displayNameAction": "Set power",
|
||||
"type": "bool",
|
||||
"defaultValue": false,
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "2261311a-4302-4a03-bd67-50e92044fe59",
|
||||
"name": "targetTemperature",
|
||||
"displayName": "Target temperature",
|
||||
"displayNameEvent": "Target temperature changed",
|
||||
"displayNameAction": "Set target temperature",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"minValue": "10",
|
||||
"maxValue": "30",
|
||||
"defaultValue": "20",
|
||||
"writable": true
|
||||
},
|
||||
{
|
||||
"id": "a2b7a3aa-641c-45b8-a13b-e845324969ca",
|
||||
"name": "temperature",
|
||||
"displayName": "Home temperature",
|
||||
"displayNameEvent": "Home temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"id": "b99b7182-51e6-456c-b7bc-f39ea2397500",
|
||||
"name": "outsideTemperature",
|
||||
"displayName": "Outside temperature",
|
||||
"displayNameEvent": "Outside temperature changed",
|
||||
"type": "double",
|
||||
"unit": "DegreeCelsius",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"id": "9b614a01-4984-4e73-8cbc-95389c484c3b",
|
||||
"name": "humidity",
|
||||
"displayName": "Humidity",
|
||||
"displayNameEvent": "Humidity changed",
|
||||
"type": "double",
|
||||
"unit": "Percentage",
|
||||
"minValue": "0",
|
||||
"maxValue": "100",
|
||||
"defaultValue": "0"
|
||||
},
|
||||
{
|
||||
"id": "59da03a6-1b61-4777-91e1-51e518beecbc",
|
||||
"name": "Mode",
|
||||
"displayName": "Mode",
|
||||
"displayNameEvent": "Mode changed",
|
||||
"displayNameAction": "Set mode",
|
||||
"type": "QString",
|
||||
"writable": true,
|
||||
"possibleValues": [
|
||||
"Automatic",
|
||||
"Cooling",
|
||||
"Heating",
|
||||
"Dehumidifier",
|
||||
"Fan"
|
||||
],
|
||||
"defaultValue": "Automatic"
|
||||
},
|
||||
{
|
||||
"id": "f63db3b7-423b-48be-be55-8ac9221316a7",
|
||||
"name": "heatingOn",
|
||||
"displayName": "Heating On",
|
||||
"displayNameEvent": "Heating changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
},
|
||||
{
|
||||
"id": "6f00a58f-248a-4137-adf5-36999adbaf50",
|
||||
"name": "coolingOn",
|
||||
"displayName": "Cooling On",
|
||||
"displayNameEvent": "Cooling changed",
|
||||
"type": "bool",
|
||||
"defaultValue": false
|
||||
}
|
||||
],
|
||||
"actionTypes": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
415
daikinairco/integrationplugindaikinairco.py
Normal file
415
daikinairco/integrationplugindaikinairco.py
Normal file
@ -0,0 +1,415 @@
|
||||
import nymea
|
||||
import time
|
||||
import threading
|
||||
import json
|
||||
import requests
|
||||
import random
|
||||
from socket import *
|
||||
import sys
|
||||
|
||||
pollTimer = None
|
||||
pollFrequency = 30
|
||||
ipMap = {}
|
||||
|
||||
def discoverThings(info):
|
||||
logger.log("Discovery started for", info.thingClassId)
|
||||
discoveredIps = findIps()
|
||||
|
||||
for i in range(0, len(discoveredIps)):
|
||||
deviceIp = discoveredIps[i]
|
||||
# get basic info /common/basic_info
|
||||
# response example:
|
||||
# ret=OK,type=aircon,reg=eu,dst=1,ver=1_14_58,rev=83B3526,pow=0,err=0,location=0,
|
||||
# name=name-in-%hex,icon=0,method=polling,port=30050,id=uuid,
|
||||
# pw=,lpw_flag=0,adp_kind=3,pv=3.30,cpv=3,cpv_minor=20,led=1,en_setzone=1,mac=mac,adp_mode=run,en_hol=0,
|
||||
# ssid1=ssid,radio1=-43,ssid=DaikinAP14937,grp_name=,en_grp=0
|
||||
|
||||
# get model info /aircon/get_model_info --> (how) can we use this?
|
||||
# response example:
|
||||
# ret=OK,model=0FC3,type=N,pv=3.30,cpv=3,cpv_minor=20,mid=NA,humd=0,s_humd=0,acled=0,land=0,elec=1,temp=1,
|
||||
# temp_rng=0,m_dtct=1,ac_dst=--,disp_dry=0,dmnd=1,en_scdltmr=1,en_frate=1,en_fdir=1,s_fdir=3,en_rtemp_a=0,
|
||||
# en_spmode=5,en_ipw_sep=1,en_mompow=1,hmlmt_l=10.0
|
||||
|
||||
aUrl = 'http://' + deviceIp + '/common/basic_info'
|
||||
headers = {'Accept': '*/*'}
|
||||
rr = requests.get(aUrl, headers=headers)
|
||||
pollResponse = rr.text
|
||||
if rr.status_code == requests.codes.ok:
|
||||
systemType = 'none'
|
||||
splitResponse = pollResponse.split(",")
|
||||
for j in range(0, len(splitResponse)):
|
||||
splitItem = splitResponse[j].split("=")
|
||||
if splitItem[0] == 'type':
|
||||
systemType = splitItem[1]
|
||||
elif splitItem[0] == 'id':
|
||||
systemId = splitItem[1]
|
||||
elif splitItem[0] == 'name':
|
||||
hexArray = splitItem[1].split("%")
|
||||
deviceName = ""
|
||||
for k in range(0, len(hexArray)):
|
||||
deviceName+=bytes.fromhex(hexArray[k]).decode('utf-8')
|
||||
if systemType == 'aircon':
|
||||
logger.log("Device with IP " + deviceIp + " is a Daikin airco unit.")
|
||||
logger.log("Device ID:", systemId)
|
||||
logger.log("Device Name:", deviceName)
|
||||
# check if device already known
|
||||
exists = False
|
||||
for thing in myThings():
|
||||
logger.log("Comparing to existing units: is %s an airco unit?" % (thing.name))
|
||||
if thing.thingClassId == aircoThingClassId:
|
||||
logger.log("Yes, %s is an airco unit." % (thing.name))
|
||||
if thing.paramValue(aircoThingDeviceIdParamTypeId) == systemId:
|
||||
logger.log("Already have unit with serial number %s in the system: %s" % (systemId, thing.name))
|
||||
exists = True
|
||||
else:
|
||||
logger.log("Thing %s doesn't match with found unit with serial number %s" % (thing.name, systemId))
|
||||
if exists == False: # unit doesn't exist yet, so add it
|
||||
thingDescriptor = nymea.ThingDescriptor(aircoThingClassId, deviceName)
|
||||
thingDescriptor.params = [
|
||||
nymea.Param(aircoThingDeviceIdParamTypeId, systemId),
|
||||
nymea.Param(aircoThingDeviceNameParamTypeId, deviceName)
|
||||
]
|
||||
info.addDescriptor(thingDescriptor)
|
||||
else: # unit already exists, so show it to allow reconfiguration
|
||||
thingDescriptor = nymea.ThingDescriptor(aircoThingClassId, deviceName, thingId=thing.id)
|
||||
thingDescriptor.params = [
|
||||
nymea.Param(aircoThingDeviceIdParamTypeId, systemId),
|
||||
nymea.Param(aircoThingDeviceNameParamTypeId, deviceName)
|
||||
]
|
||||
info.addDescriptor(thingDescriptor)
|
||||
else:
|
||||
logger.log("Device with IP " + deviceIp + " does not appear to be a supported Daikin airco unit.")
|
||||
else:
|
||||
logger.log("Device with IP " + deviceIp + " does not appear to be a supported Daikin airco unit.")
|
||||
info.finish(nymea.ThingErrorNoError)
|
||||
return
|
||||
|
||||
def findIps():
|
||||
discoveredIps = []
|
||||
|
||||
# Create a UDP socket
|
||||
sock = socket(AF_INET, SOCK_DGRAM)
|
||||
sock.setsockopt(SOL_SOCKET, SO_REUSEADDR, 1)
|
||||
sock.setsockopt(SOL_SOCKET, SO_BROADCAST, 1)
|
||||
sock.settimeout(20)
|
||||
|
||||
server_address = ('255.255.255.255', 30050)
|
||||
message = 'DAIKIN_UDP/common/basic_info'
|
||||
|
||||
try:
|
||||
while True:
|
||||
# Send data
|
||||
logger.log('sending: ' + message)
|
||||
sent = sock.sendto(message.encode(), server_address)
|
||||
|
||||
# Receive response
|
||||
logger.log('waiting to receive')
|
||||
data, server = sock.recvfrom(4096)
|
||||
if data.decode('UTF-8')[0:18] == 'ret=OK,type=aircon':
|
||||
print('Received confirmation; server ip: ' + str(server[0]) )
|
||||
discoveredIps.append(str(server[0]))
|
||||
break
|
||||
else:
|
||||
print('Verification failed')
|
||||
|
||||
print('Trying again...')
|
||||
finally:
|
||||
sock.close()
|
||||
return discoveredIps
|
||||
|
||||
def findDeviceIP(airco):
|
||||
searchSystemId = airco.paramValue(aircoThingDeviceIdParamTypeId)
|
||||
discoveredIps = findIps()
|
||||
foundIp = None
|
||||
found = False
|
||||
for i in range(0, len(discoveredIps)):
|
||||
deviceIp = discoveredIps[i]
|
||||
aUrl = 'http://' + deviceIp + '/common/basic_info'
|
||||
headers = {'Accept': '*/*'}
|
||||
rr = requests.get(aUrl, headers=headers)
|
||||
pollResponse = rr.text
|
||||
if rr.status_code == requests.codes.ok:
|
||||
logger.log("Device with IP " + deviceIp + " is a supported Daikin Airco.")
|
||||
# get device info
|
||||
splitResponse = pollResponse.split(",")
|
||||
for j in range(0, len(splitResponse)):
|
||||
splitItem = splitResponse[j].split("=")
|
||||
if splitItem[0] == 'id':
|
||||
systemId = splitItem[1]
|
||||
logger.log("Device ID:", systemId)
|
||||
# check if this is the device with the serial number we're looking for
|
||||
if systemId == searchSystemId:
|
||||
logger.log("Device with IP " + deviceIp + " is the existing device.")
|
||||
found = True
|
||||
foundIp = deviceIp
|
||||
ipMap[airco] = foundIp
|
||||
else:
|
||||
logger.log("Device with IP " + deviceIp + " does not appear to be a supported Daikin Airco.")
|
||||
if found == True:
|
||||
airco.setStateValue(aircoConnectedStateTypeId, True)
|
||||
else:
|
||||
airco.setStateValue(aircoConnectedStateTypeId, False)
|
||||
return found
|
||||
|
||||
def setupThing(info):
|
||||
searchSystemId = info.thing.paramValue(aircoThingDeviceIdParamTypeId)
|
||||
logger.log("setupThing called for", info.thing.name, searchSystemId)
|
||||
found = findDeviceIP(info.thing)
|
||||
if found == True:
|
||||
pollAirco(info.thing)
|
||||
info.finish(nymea.ThingErrorNoError)
|
||||
else:
|
||||
info.finish(nymea.ThingErrorHardwareFailure, "Error connecting to the device in the network.")
|
||||
|
||||
logger.log("Airco added:", info.thing.name)
|
||||
|
||||
# If no poll timer is set up yet, start it now
|
||||
logger.log("Creating pollService")
|
||||
global pollTimer
|
||||
global pollFrequency
|
||||
if pollTimer == None:
|
||||
logger.log("Starting timer @ setupThing")
|
||||
pollTimer = nymea.PluginTimer(pollFrequency, pollService)
|
||||
logger.log("timer interval @ setupThing", pollTimer.interval)
|
||||
else:
|
||||
logger.log("Timer already exists @ setupThing")
|
||||
|
||||
info.finish(nymea.ThingErrorNoError)
|
||||
return
|
||||
|
||||
def pollAirco(info):
|
||||
global pollFrequency
|
||||
global ipMap
|
||||
deviceIp = ipMap[info]
|
||||
logger.log("polling airco", deviceIp, info.name)
|
||||
airco = info
|
||||
headers = {'Accept': '*/*'}
|
||||
# get sensor info
|
||||
# response example:
|
||||
# ret=OK,htemp=25.0,hhum=30,otemp=2.0,err=0,cmpfreq=0,mompow=1
|
||||
aUrl = 'http://' + deviceIp + '/aircon/get_sensor_info'
|
||||
pr = requests.get(aUrl, headers=headers)
|
||||
pollResponse = pr.text
|
||||
if pr.status_code == requests.codes.ok:
|
||||
airco.setStateValue(aircoConnectedStateTypeId, True)
|
||||
splitResponse = pollResponse.split(",")
|
||||
for i in range(0, len(splitResponse)):
|
||||
splitItem = splitResponse[i].split("=")
|
||||
if splitItem[0] == 'htemp':
|
||||
homeTemp = float(splitItem[1])
|
||||
airco.setStateValue(aircoTemperatureStateTypeId, homeTemp)
|
||||
elif splitItem[0] == 'hhum':
|
||||
homeHumidity = float(splitItem[1])
|
||||
airco.setStateValue(aircoHumidityStateTypeId, homeHumidity)
|
||||
elif splitItem[0] == 'otemp':
|
||||
outTemp = float(splitItem[1])
|
||||
airco.setStateValue(aircoOutsideTemperatureStateTypeId, outTemp)
|
||||
else:
|
||||
airco.setStateValue(aircoConnectedStateTypeId, False)
|
||||
#device disconnected, IP may have changed, so search again
|
||||
found = findDeviceIP(airco)
|
||||
if found == False:
|
||||
return
|
||||
|
||||
# get control info
|
||||
# response example:
|
||||
# ret=OK,pow=0,mode=4,adv=,stemp=21.0,shum=0,dt1=22.0,dt2=M,dt3=20.0,dt4=21.0,dt5=21.0,dt7=22.0,
|
||||
# dh1=0,dh2=0,dh3=0,dh4=0,dh5=0,dh7=0,dhh=50,b_mode=4,b_stemp=21.0,b_shum=0,alert=255,
|
||||
# f_rate=A,f_dir=0,b_f_rate=A,b_f_dir=0,dfr1=A,dfr2=A,dfr3=A,dfr4=A,dfr5=A,dfr6=A,dfr7=A,dfrh=5,
|
||||
# dfd1=0,dfd2=0,dfd3=0,dfd4=0,dfd5=0,dfd6=0,dfd7=0,dfdh=0,dmnd_run=0,en_demand=1
|
||||
aUrl = 'http://' + deviceIp + '/aircon/get_control_info'
|
||||
pr = requests.get(aUrl, headers=headers)
|
||||
pollResponse = pr.text
|
||||
if pr.status_code == requests.codes.ok:
|
||||
airco.setStateValue(aircoConnectedStateTypeId, True)
|
||||
splitResponse = pollResponse.split(",")
|
||||
for i in range(0, len(splitResponse)):
|
||||
splitItem = splitResponse[i].split("=")
|
||||
# get power state
|
||||
if splitItem[0] == 'pow':
|
||||
power = int(splitItem[1])
|
||||
logger.log("Power", power)
|
||||
airco.setStateValue(aircoPowerStateTypeId, power)
|
||||
elif splitItem[0] == 'mode':
|
||||
mode = int(splitItem[1])
|
||||
if mode == 2: # 2 = dehumidifier mode
|
||||
logger.log("Airco mode: dehumidifier", mode)
|
||||
airco.setStateValue(aircoModeStateTypeId, "Dehumidifier")
|
||||
elif mode == 3: # 3 = cooling mode
|
||||
logger.log("Airco mode: cooling", mode)
|
||||
airco.setStateValue(aircoModeStateTypeId, "Cooling")
|
||||
elif mode == 4: # 4 = heating mode
|
||||
logger.log("Airco mode: heating", mode)
|
||||
airco.setStateValue(aircoModeStateTypeId, "Heating")
|
||||
elif mode == 6: # 6 = fan mode
|
||||
logger.log("Airco mode: fan", mode)
|
||||
airco.setStateValue(aircoModeStateTypeId, "Fan")
|
||||
else: # 0-1-7 = automatic mode
|
||||
logger.log("Airco mode: automatic", mode)
|
||||
airco.setStateValue(aircoModeStateTypeId, "Automatic")
|
||||
elif splitItem[0] == 'stemp':
|
||||
try:
|
||||
targetTemp = float(splitItem[1])
|
||||
logger.log("Target temperature", targetTemp)
|
||||
airco.setStateValue(aircoTargetTemperatureStateTypeId, targetTemp)
|
||||
except:
|
||||
logger.log("Target temperature parameter is not a number:", splitItem[1])
|
||||
for j in range(0, len(splitResponse)):
|
||||
splitItem = splitResponse[j].split("=")
|
||||
if splitItem[0] == 'dt1':
|
||||
targetTemp = float(splitItem[1])
|
||||
logger.log("Using target temperature from automatic mode", targetTemp)
|
||||
airco.setStateValue(aircoTargetTemperatureStateTypeId, targetTemp)
|
||||
else:
|
||||
airco.setStateValue(aircoConnectedStateTypeId, False)
|
||||
|
||||
#set heatingOn / coolingOn based on mode, temperature & target temperature (API doesn't seem to return it)
|
||||
targetTemperature = airco.stateValue(aircoTargetTemperatureStateTypeId)
|
||||
temperature = airco.stateValue(aircoTemperatureStateTypeId)
|
||||
mode = airco.stateValue(aircoModeStateTypeId)
|
||||
power = airco.stateValue(aircoPowerStateTypeId)
|
||||
if mode == "Cooling" and power == True:
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, False)
|
||||
if targetTemperature < temperature:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, True)
|
||||
else:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, False)
|
||||
elif mode == "Heating" and power == True:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, False)
|
||||
if targetTemperature > temperature:
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, True)
|
||||
else:
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, False)
|
||||
elif mode == "Automatic" and power == True:
|
||||
if targetTemperature == temperature:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, False)
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, False)
|
||||
elif targetTemperature > temperature:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, False)
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, True)
|
||||
else:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, True)
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, False)
|
||||
else:
|
||||
airco.setStateValue(aircoCoolingOnStateTypeId, False)
|
||||
airco.setStateValue(aircoHeatingOnStateTypeId, False)
|
||||
|
||||
def pollService():
|
||||
logger.log("pollTimer triggered")
|
||||
global pollTimer
|
||||
global pollFrequency
|
||||
pollTimer.interval = pollFrequency
|
||||
# Poll all airco units we know
|
||||
for thing in myThings():
|
||||
if thing.thingClassId == aircoThingClassId:
|
||||
pollAirco(thing)
|
||||
|
||||
def executeAction(info):
|
||||
global ipMap
|
||||
deviceIp = ipMap[info.thing]
|
||||
logger.log("executeAction called for thing", info.thing.name, deviceIp, info.actionTypeId, info.params)
|
||||
headers = {'Accept': '*/*'}
|
||||
aUrl = 'http://' + deviceIp + '/aircon/get_control_info'
|
||||
pr = requests.get(aUrl, headers=headers)
|
||||
# get control info, to obtain target temperature per mode, to set the correct target temperature (stemp) when changing mode
|
||||
pollResponse = pr.text
|
||||
logger.log("response", pr.text)
|
||||
if pr.status_code == requests.codes.ok:
|
||||
info.thing.setStateValue(aircoConnectedStateTypeId, True)
|
||||
splitResponse = pollResponse.split(",")
|
||||
for i in range(0, len(splitResponse)):
|
||||
splitItem = splitResponse[i].split("=")
|
||||
if splitItem[0] == 'pow':
|
||||
power = int(splitItem[1])
|
||||
elif splitItem[0] == 'mode':
|
||||
mode = int(splitItem[1])
|
||||
elif splitItem[0] == 'stemp':
|
||||
targetTemp = splitItem[1]
|
||||
elif splitItem[0] == 'shum':
|
||||
targetHum = splitItem[1]
|
||||
elif splitItem[0] == 'f_rate':
|
||||
f_rate = splitItem[1]
|
||||
elif splitItem[0] == 'f_dir':
|
||||
f_dir = splitItem[1]
|
||||
elif splitItem[0] == 'dt1':
|
||||
dt1 = splitItem[1]
|
||||
elif splitItem[0] == 'dt2':
|
||||
dt2 = splitItem[1]
|
||||
elif splitItem[0] == 'dt3':
|
||||
dt3 = splitItem[1]
|
||||
elif splitItem[0] == 'dt4':
|
||||
dt4 = splitItem[1]
|
||||
elif splitItem[0] == 'dt5':
|
||||
dt5 = splitItem[1]
|
||||
elif splitItem[0] == 'dt7':
|
||||
dt7 = splitItem[1]
|
||||
elif splitItem[0] == 'dh1':
|
||||
dh1 = splitItem[1]
|
||||
elif splitItem[0] == 'dh2':
|
||||
dh2 = splitItem[1]
|
||||
elif splitItem[0] == 'dh3':
|
||||
dh3 = splitItem[1]
|
||||
elif splitItem[0] == 'dh4':
|
||||
dh4 = splitItem[1]
|
||||
elif splitItem[0] == 'dh5':
|
||||
dh5 = splitItem[1]
|
||||
elif splitItem[0] == 'dh7':
|
||||
dh7 = splitItem[1]
|
||||
else:
|
||||
info.thing.setStateValue(aircoConnectedStateTypeId, False)
|
||||
info.finish(nymea.ThingErrorNoError)
|
||||
|
||||
if info.actionTypeId == aircoPowerActionTypeId:
|
||||
power = info.paramValue(aircoPowerActionPowerParamTypeId)
|
||||
if power == True:
|
||||
power = 1
|
||||
elif power == False:
|
||||
power = 0
|
||||
logger.log("new power value", power)
|
||||
elif info.actionTypeId == aircoTargetTemperatureActionTypeId:
|
||||
targetTemp = str(info.paramValue(aircoTargetTemperatureActionTargetTemperatureParamTypeId))
|
||||
logger.log("new target temperature", targetTemp)
|
||||
elif info.actionTypeId == aircoModeActionTypeId:
|
||||
targetMode = info.paramValue(aircoModeActionModeParamTypeId)
|
||||
if targetMode == "Automatic":
|
||||
mode = 0
|
||||
targetTemp = dt1
|
||||
targetHum = dh1
|
||||
elif targetMode == "Cooling":
|
||||
mode = 3
|
||||
targetTemp = dt3
|
||||
targetHum = dh3
|
||||
elif targetMode == "Heating":
|
||||
mode = 4
|
||||
targetTemp = dt4
|
||||
targetHum = dh4
|
||||
elif targetMode == "Dehumidifier":
|
||||
mode = 2
|
||||
targetTemp = dt2
|
||||
targetHum = dh2
|
||||
elif targetMode == "Fan":
|
||||
mode = 6
|
||||
logger.log("new target mode:", targetMode, mode)
|
||||
|
||||
# mandatory parameters: pow, mode, stemp, shum, f_rate, f_dir (f_rate & f_dir can't be set from the plugin yet, so we always use the values obtained above)
|
||||
param = "pow="+str(power)+"&mode="+str(mode)+"&stemp="+targetTemp+"&shum="+targetHum+"&f_rate="+f_rate+"&f_dir="+f_dir
|
||||
logger.log("parameters", param)
|
||||
aUrl = "http://" + deviceIp + "/aircon/set_control_info?"+param
|
||||
pr = requests.post(aUrl, headers=headers)
|
||||
time.sleep(0.5)
|
||||
pollAirco(info.thing)
|
||||
info.finish(nymea.ThingErrorNoError)
|
||||
return
|
||||
|
||||
def deinit():
|
||||
global pollTimer
|
||||
# If we started a poll timer, cancel it on shutdown.
|
||||
if pollTimer is not None:
|
||||
pollTimer = None
|
||||
|
||||
def thingRemoved(thing):
|
||||
global pollTimer
|
||||
logger.log("removeThing called for", thing.name)
|
||||
# Clean up all data related to this thing
|
||||
if len(myThings()) == 0 and pollTimer is not None:
|
||||
pollTimer = None
|
||||
14
daikinairco/meta.json
Normal file
14
daikinairco/meta.json
Normal file
@ -0,0 +1,14 @@
|
||||
{
|
||||
"title": "Daikin Airco",
|
||||
"tagline": "Discover and control Daikin airconditioning devices",
|
||||
"icon": "daikin.jpg",
|
||||
"stability": "community",
|
||||
"offline": true,
|
||||
"technologies": [
|
||||
"network"
|
||||
],
|
||||
"categories": [
|
||||
"appliance",
|
||||
"heating"
|
||||
]
|
||||
}
|
||||
73
daikinairco/requirements.txt
Normal file
73
daikinairco/requirements.txt
Normal file
@ -0,0 +1,73 @@
|
||||
testresources==2.0.1 \
|
||||
--hash=sha256:67a361c3a2412231963b91ab04192209aa91a1aa052f0ab87245dbea889d1282 \
|
||||
--hash=sha256:ee9d1982154a1e212d4e4bac6b610800bfb558e4fb853572a827bc14a96e4417
|
||||
requests==2.27.1 \
|
||||
--hash=sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61 \
|
||||
--hash=sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d
|
||||
urllib3==1.26.9 \
|
||||
--hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \
|
||||
--hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e
|
||||
chardet==4.0.0 \
|
||||
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa \
|
||||
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
|
||||
lazr.uri==1.0.6 \
|
||||
--hash=sha256:5026853fcbf6f91d5a6b11ea7860a641fe27b36d4172c731f4aa16b900cf8464 \
|
||||
--hash=sha256:55281b3890c297a89df3dc94d388cbd0ef6750bf1642024d208ee3c71ac8766b
|
||||
six==1.16.0 \
|
||||
--hash=sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926 \
|
||||
--hash=sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254
|
||||
wadllib==1.3.6 \
|
||||
--hash=sha256:acd9ad6a2c1007d34ca208e1da6341bbca1804c0e6850f954db04bdd7666c5fc \
|
||||
--hash=sha256:919acbaa442f35c0f82a86b5af2411595ba72f9c9099d203f965a1d7ecf89447
|
||||
lazr.restfulclient==0.14.4 \
|
||||
--hash=sha256:bf0fd6b2749b3a2d02711f854c9d23704756f7afed21fb5d5b9809d72aa6d087 \
|
||||
--hash=sha256:ad207c985d4544b522aeab0ebabfd9345a9a767d2e111ff69117a3c64fcc415d
|
||||
pyparsing==3.0.8 \
|
||||
--hash=sha256:7bf433498c016c4314268d95df76c81b842a4cb2b276fa3312cfb1e1d85f6954 \
|
||||
--hash=sha256:ef7b523f6356f763771559412c0d7134753f037822dad1b16945b7b846f7ad06
|
||||
certifi==2021.10.8 \
|
||||
--hash=sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872 \
|
||||
--hash=sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569
|
||||
setuptools==62.1.0 \
|
||||
--hash=sha256:26ead7d1f93efc0f8c804d9fafafbe4a44b179580a7105754b245155f9af05a8 \
|
||||
--hash=sha256:47c7b0c0f8fc10eec4cf1e71c6fdadf8decaa74ffa087e68cd1c20db7ad6a592
|
||||
pbr==5.8.1 \
|
||||
--hash=sha256:27108648368782d07bbf1cb468ad2e2eeef29086affd14087a6d04b7de8af4ec \
|
||||
--hash=sha256:66bc5a34912f408bb3925bf21231cb6f59206267b7f63f3503ef865c1a292e25
|
||||
distro==1.7.0 \
|
||||
--hash=sha256:151aeccf60c216402932b52e40ee477a939f8d58898927378a02abbe852c1c39 \
|
||||
--hash=sha256:d596311d707e692c2160c37807f83e3820c5d539d5a83e87cfb6babd8ba3a06b
|
||||
oauthlib==3.2.0 \
|
||||
--hash=sha256:23a8208d75b902797ea29fd31fa80a15ed9dc2c6c16fe73f5d346f83f6fa27a2 \
|
||||
--hash=sha256:6db33440354787f9b7f3a6dbd4febf5d0f93758354060e802f6c06cb493022fe
|
||||
requests-oauthlib==1.3.1 \
|
||||
--hash=sha256:2577c501a2fb8d05a304c09d090d6e47c306fef15809d102b327cf8364bddab5 \
|
||||
--hash=sha256:75beac4a47881eeb94d5ea5d6ad31ef88856affe2332b9aafb52c6452ccf0d7a
|
||||
urllib3==1.26.9 \
|
||||
--hash=sha256:44ece4d53fb1706f667c9bd1c648f5469a2ec925fcf3a776667042d645472c14 \
|
||||
--hash=sha256:aabaf16477806a5e1dd19aa41f8c2b7950dd3c746362d7e3223dbe6de6ac448e
|
||||
chardet==4.0.0 \
|
||||
--hash=sha256:0d6f53a15db4120f2b08c94f11e7d93d2c911ee118b6b30a04ec3ee8310179fa \
|
||||
--hash=sha256:f864054d66fd9118f2e67044ac8981a54775ec5b67aed0441892edb553d21da5
|
||||
httplib2==0.20.4 \
|
||||
--hash=sha256:58a98e45b4b1a48273073f905d2961666ecf0fbac4250ea5b47aef259eb5c585 \
|
||||
--hash=sha256:8b6a905cb1c79eefd03f8669fd993c36dc341f7c558f056cb5a33b5c2f458543
|
||||
ifaddr==0.1.7 \
|
||||
--hash=sha256:1f9e8a6ca6f16db5a37d3356f07b6e52344f6f9f7e806d618537731669eb1a94 \
|
||||
--hash=sha256:d1f603952f0a71c9ab4e705754511e4e03b02565bc4cec7188ad6415ff534cd3
|
||||
charset-normalizer==2.0.12 \
|
||||
--hash=sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597 \
|
||||
--hash=sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df
|
||||
idna==3.3 \
|
||||
--hash=sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff \
|
||||
--hash=sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d
|
||||
importlib-metadata==3.7.0 \
|
||||
--hash=sha256:24499ffde1b80be08284100393955842be4a59c7c16bbf2738aad0e464a8e0aa \
|
||||
--hash=sha256:c6af5dbf1126cd959c4a8d8efd61d4d3c83bddb0459a17e554284a077574b614
|
||||
typing-extensions==3.7.4.3 \
|
||||
--hash=sha256:7cb407020f00f7bfc3cb3e7881628838e69d8f3fcab2f64742a5e76b2f841918 \
|
||||
--hash=sha256:99d4073b617d30288f569d3f13d2bd7548c3a7e4c8de87db09a9d29bb3a4a60c \
|
||||
--hash=sha256:dafc7639cde7f1b6e1acc0f457842a83e722ccca8eef5270af2d74792619a89f
|
||||
zipp==3.4.1 \
|
||||
--hash=sha256:3607921face881ba3e026887d8150cca609d517579abe052ac81fc5aeffdbd76 \
|
||||
--hash=sha256:51cb66cc54621609dd593d1787f286ee42a5c0adbb4b29abea5a63edc3e03098
|
||||
9
debian/control
vendored
9
debian/control
vendored
@ -162,6 +162,15 @@ Description: nymea.io plugin for commandlauncher
|
||||
This package will install the nymea.io plugin for commandlauncher
|
||||
|
||||
|
||||
Package: nymea-plugin-daikinairco
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
${misc:Depends},
|
||||
python3-pip,
|
||||
Description: nymea integration plugin for Daikin airconditioning units
|
||||
This package contains the nymea integration plugin for Daikin airconditioning units.
|
||||
|
||||
|
||||
Package: nymea-plugin-datetime
|
||||
Architecture: any
|
||||
Depends: ${shlibs:Depends},
|
||||
|
||||
3
debian/nymea-plugin-daikinairco.install.in
vendored
Normal file
3
debian/nymea-plugin-daikinairco.install.in
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
daikinairco/integrationplugindaikinairco.json usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/daikinairco/
|
||||
daikinairco/integrationplugindaikinairco.py usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/daikinairco/
|
||||
daikinairco/requirements.txt usr/lib/@DEB_HOST_MULTIARCH@/nymea/plugins/daikinairco/
|
||||
Loading…
x
Reference in New Issue
Block a user