Git Product home page Git Product logo

Comments (4)

Ericmas001 avatar Ericmas001 commented on August 19, 2024 1

Hi !
I personnally use it everyday with a rpi-zero-w with Minibian installed.

The important thing is:
When you use "hvac = Mitsubishi(23, LogLevel.ErrorsOnly)", 23 is the GPIO number, not the PIN number
My IR led is on GPIO 23 (Pin 16).
untitled

I will give you more info than you need, so you can reproduce something close to my setup.
This is my setup:
https://github.com/Ericmas001/pi-adventures/blob/master/general/minibian_initial_setup.md

Then I installed:

sudo apt-get install git -y
sudo apt-get install python python-dev python-pip python-rpi.gpio pigpio -y
sudo pip install git+https://github.com/Ericmas001/HVAC-IR-Control
sudo pip install pigpio
sudo pip install flask

I use flask and a little webservice to control it, but that is not madatory.
My IR led is on GPIO 23 (Pin 16).

app.py

#!/usr/bin/python

import logging 
from logging.handlers import RotatingFileHandler
from datetime import datetime, time
from flask import Flask, request, jsonify
from flask.json import JSONEncoder
import handler

class CustomJSONEncoder(JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime):
            return obj.isoformat()
        if isinstance(obj, time):
            return obj.isoformat()
        
        return obj.__dict__

class MyFlask(Flask):
    def make_response(self, rv):
        if hasattr(rv, 'response') and rv.response is None:
            return super(MyFlask, self).make_response(rv)
        if hasattr(rv, 'new_url') and rv.new_url is not None:
            return super(MyFlask, self).make_response(rv)
        return super(MyFlask, self).make_response(jsonify(rv))

app = MyFlask(__name__)
app.json_encoder = CustomJSONEncoder

@app.route('/config/', methods=['GET'])
def list_config():
    return handler.list_config(app)

@app.route('/hvac/off/', methods=['GET'])
def power_off():
    return handler.power_off(app)

@app.route('/hvac/on/', methods=['GET'])
def power_on():
    return handler.send_last_command(app)

@app.route('/hvac/command/', methods=['POST'])
def send_command():
    return handler.send_command(app, request.json)

@app.route('/last/command/', methods=['GET'])
def last_command():
    return handler.last_command(app)

if __name__ == '__main__':
    app.run(debug=True, host='0.0.0.0', port=4242)

handler.py

#!/usr/bin/python
from hvac_ircontrol.ir_sender import LogLevel
from hvac_ircontrol.mitsubishi import Mitsubishi, ClimateMode, FanMode, VanneVerticalMode, VanneHorizontalMode, ISeeMode, AreaMode, PowerfulMode, Constants
from models import *
import inspect
import json
from collections import namedtuple
import datetime
import traceback
import os

path = "/hvac/last_config.json"

def list_config(app):
    res = AvailableCommands()
    res.climate_modes = __list_attributes(ClimateMode)
    res.isee_modes = __list_attributes(ISeeMode)
    res.powerful_modes = __list_attributes(PowerfulMode)
    res.vanne_horizontal_modes = __list_attributes(VanneHorizontalMode)
    res.fan_modes = __list_attributes(FanMode)
    res.vanne_vertical_modes = __list_attributes(VanneVerticalMode)
    res.area_modes = __list_attributes(AreaMode)
    res.min_temp = Constants.MinTemp
    res.max_temp = Constants.MaxTemp
    return res

def power_off(app):
    hvac = Mitsubishi(23, LogLevel.ErrorsOnly)
    hvac.power_off()
    return "It was powered OFF"

def last_command(app):
    command = HvacCommand()
    if os.path.isfile(path):
        with open(path, 'r') as content_file:
            data = json.loads(content_file.read())
            command.from_json(data)
    return command

def send_command(app, data):
    command = HvacCommand()
    command.from_json(data)
    return __send_command(app, command)

def send_last_command(app):
    return __send_command(app, last_command(app))

def __send_command(app, command):
    try:
        hvac = Mitsubishi(23, LogLevel.Minimal)
        args = dict(
            climate_mode=__get_value(ClimateMode, command.climate_mode),
            temperature=command.temperature,
            fan_mode=__get_value(FanMode, command.fan_mode),
            vanne_vertical_mode=__get_value(VanneVerticalMode, command.vanne_vertical_mode),
            vanne_horizontal_mode=__get_value(VanneHorizontalMode, command.vanne_horizontal_mode),
            isee_mode=__get_value(ISeeMode, command.isee_mode),
            area_mode=__get_value(AreaMode, command.area_mode),
            start_time = __get_time_value(command.start_time),
            end_time = __get_time_value(command.end_time),
            powerful=__get_value(PowerfulMode, command.powerful_mode))
        hvac.send_command(**args)

        cfg = open(path, "w")
        cfg.write(command.to_json())
        return HvacCommandResponse(True,command,args)
    except:
        app.logger.error("There was an error: {0}".format(traceback.format_exc()))
        return HvacCommandResponse(False,data,"There was an error: {0}".format(traceback.format_exc()))

def __list_attributes(my_type):
    return [a[0] for a in inspect.getmembers(my_type, lambda c:not(inspect.isroutine(c))) if not a[0].startswith('_')]

def __get_value(my_type, my_value):
    return [a[1] for a in inspect.getmembers(my_type, lambda c:not(inspect.isroutine(c))) if a[0] == my_value][0]

def __get_time_value(my_value):
    if my_value is None or my_value < 0 or my_value >= 24:
        return None
    
    return datetime.time(int(my_value)//1, int((my_value*100)%100))

models.py

import json

class AvailableCommands:
    def __init__(self):
        self.climate_modes = []
        self.isee_modes = []
        self.powerful_modes = []
        self.vanne_horizontal_modes = []
        self.fan_modes = []
        self.vanne_vertical_modes = []
        self.area_modes = []
        self.min_temp = -1
        self.max_temp = -1

class HvacCommandResponse:
    def __init__(self, success, command, decoded):
        self.success = success
        self.command = command
        self.decoded_command = decoded

class HvacCommand:
    def __init__(self):
        self.climate_mode = "Cold"
        self.isee_mode = "ISeeOn"
        self.powerful_mode = "PowerfulOff"
        self.vanne_horizontal_mode = "NotSet"
        self.fan_mode = "Auto"
        self.vanne_vertical_mode = "Auto"
        self.area_mode = "NotSet"
        self.temperature = 21
        self.start_time = None
        self.end_time = None
    
    def from_json(self, data):
        self.climate_mode = data["climate_mode"]
        self.isee_mode = data["isee_mode"]
        self.powerful_mode = data["powerful_mode"]
        self.vanne_horizontal_mode = data["vanne_horizontal_mode"]
        self.fan_mode = data["fan_mode"]
        self.vanne_vertical_mode = data["vanne_vertical_mode"]
        self.area_mode = data["area_mode"]
        self.temperature = data["temperature"]
        self.start_time = data["start_time"]
        self.end_time = data["end_time"]

    def to_json(self):
        return json.dumps(self.__dict__, sort_keys=True, indent=4, separators=(',', ': '))

and some communication examples:

I/REQUEST: http://localhost:4242/hvac/off/
I/METHOD: GET
I/RESPONSE: "It was powered OFF"
I/REQUEST: http://localhost:4242/hvac/on/
I/DATA:
{
  "climate_mode": "Hot",
  "isee_mode": "ISeeOn",
  "powerful_mode": "PowerfulOff",
  "vanne_horizontal_mode": "NotSet",
  "fan_mode": "Auto",
  "vanne_vertical_mode": "Auto",
  "area_mode": "Full",
  "temperature": 21,
  "start_time": -1,
  "end_time": -1
}
I/METHOD: POST
I/RESPONSE:
{
  "command": {
    "area_mode": "Full",
    "climate_mode": "Hot",
    "end_time": -1,
    "fan_mode": "Auto",
    "isee_mode": "ISeeOn",
    "powerful_mode": "PowerfulOff",
    "start_time": -1,
    "temperature": 21,
    "vanne_horizontal_mode": "NotSet",
    "vanne_vertical_mode": "Auto"
  },
  "decoded_command": {
    "area_mode": 128,
    "climate_mode": 8,
    "end_time": null,
    "fan_mode": 128,
    "isee_mode": 64,
    "powerful": 0,
    "start_time": null,
    "temperature": 21,
    "vanne_horizontal_mode": 0,
    "vanne_vertical_mode": 64
  },
  "success": true
}

from hvac-ir-control.

gouldner avatar gouldner commented on August 19, 2024

@Ericmas001
Great instructions for Raspberry! Thanks. If I run your Flask code as root it works fine. But if I run it as pi I get an error. and nothing is sent. (Code still returns success but I tested and signal isn't sent)
2018-08-16 20:55:53 gpioSetMode: pigpio uninitialised, call gpioInitialise()
2018-08-16 20:55:53 gpioWaveClear: pigpio uninitialised, call gpioInitialise()
Error in clearing wave!
127.0.0.1 - - [16/Aug/2018 20:55:53] "GET /hvac/off/ HTTP/1.1" 200 -

my user "pi" is in the group gpio and I am updated to the latest version of stretch. Any idea how to make this work running as pi instead of having a web service running as root?

from hvac-ir-control.

lumanga avatar lumanga commented on August 19, 2024

@Ericmas001

Dear Sir,
I have Raspberry pi 3 with Raspbian LITE OS.
I have Broadlink Mini R3 connected to my WiFi. I have IP and MAC of Broadlink inserted into the .py file.
I have installed "sudo pip3 install broadlink" and all the files of this project.
If I do in terminal:
pi@CyberPiLITE:$ python3 SendHVACCmdToRM2.py
I receive:
26022601703a0e2a0e2a0e0d0e0d0e0d0e2a0e0d0e0d0e2a0e2a0e0d0e2a0e0d0e0d0e2a0e2a0e0d0e2a0e2a0e0d0e0d0e2a0e0d0e0d0e2a0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e2a0e2a0e0d0e0d0e0d0e2a0e0d0e2a0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e2a0e2a0e0d0e0d0e2a0e2a0e0d0e0d0e0d0e0d0e2a0e2a0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e0d0e2a0e2a0e0d0e2a0e0d0e2a0e0d0e0d0f0032020d

so python works!

Even if I do:
pi@CyberPiLITE: $ python3 SendHVACCmdToRM2.py -h
I receive:
`
usage: SendHVACCmdToRM2.py [-h] [-t HVAC_TEMPERATURE] [-p]
[-c HVAC_CLIMATE_CODE] [-Vv HVAC_VANNE_V_CODE]
[-F HVAC_FAN_MODE] [--version]

Short sample python HVAC_IR command sender to Broadlink RM2 Mini
optional arguments:
-h, --help show this help message and exit
-t HVAC_TEMPERATURE, --temperature HVAC_TEMPERATURE
Set HVAC Temperature in Celcius, Ex: 21
-p, --power HVAC Power, default = Power Off
-c HVAC_CLIMATE_CODE, --climate HVAC_CLIMATE_CODE
Define Climate Code : C=Cold, H=HOT
-Vv HVAC_VANNE_V_CODE, --vanne_vertical HVAC_VANNE_V_CODE
Define Vertical Vanne Mode : A=Automatic, S=Swing,
B=Bottom, T:Top
-F HVAC_FAN_MODE, --fan HVAC_FAN_MODE
Define Fan speed : A=Automatic, L=Low, M=Middle,
F=Fast, S=Silent
`
So I don't understand the command to use after to let my MSD-FD25 work

For example POWER ON, COLD, 23°C, van AUTO, fan AUTO??

from hvac-ir-control.

jgroezin avatar jgroezin commented on August 19, 2024

Thanks for the code and the explanation. Running your python on RPI. Still figuring this out a bit but defintely controls my HVAC.

from hvac-ir-control.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.