Coder Social home page Coder Social logo

python-nuheat's People

Contributors

broox avatar dependabot[bot] avatar tstabrawa avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

python-nuheat's Issues

Add Emerson Warm Tiles support

Per @keithnet, the APIs are the same.

The hostname for warm tiles is: warmtiles.mythermostat.info

The data returned by a Warm Tiles thermostat seems to have a few properties that are different than that of NuHeat.

WarmTiles has these additional fields:

  • ComfortEndTime
  • ComfortTemperature
  • DistributorId
  • EarlyStartOfHeating
  • LastPrimaryModeIsAuto
  • LoadManuallySetWatt
  • LoadMeasuredWatt
  • LoadMeasuringActive
  • ManualTemperature
  • RegulationMode - maybe the same as ScheduleMode?
  • VacationBeginDay
  • VacationEnabled
  • VacationEndDay
  • VacationTemperature
  • 2 additional ScheduleType values (0-5)

WarmTiles is missing these NuHeat fields:

  • EnergyOverview
  • HoldSetPointDateTime
  • OperatingMode
  • ScheduleMode
  • WPerSquareUnit

Example Warm Tiles response:

{
    "Assigned":true,
    "ComfortEndTime":"11/01/2023 12:00:00 +00:00",
    "ComfortTemperature":500,
    "Confirmed":true,
    "DistributerId":18231,
    "EarlyStartOfHeating":false,
    "Email":"[email protected]",
    "ErrorCode":0,
    "GroupId":-1,
    "GroupName":"Home",
    "HasBeenAssigned":true,
    "Heating":false,
    "KwhCharge":0.25,
    "LastPrimaryModeIsAuto":false,
    "LoadManuallySetWatt":100,
    "LoadMeasuredWatt":2346,
    "LoadMeasuringActive":true,
    "ManualTemperature":500,
    "MaxTemp":4000,
    "MinTemp":500,
    "Online":true,
    "RegulationMode":3,
    "Room":"Porch",
    "SerialNumber":"0000000",
    "SetPointTemp":500,
    "SWVersion":"1012S202",
    "Temperature":714,
    "TZOffset":"-06:00",
    "VacationBeginDay":"01/01/1970 00:00:00",
    "VacationEnabled":false,
    "VacationEndDay":"01/01/1970 00:00:00",
    "VacationTemperature":500,
    "Schedules":[
        {
            "WeekDayGrpNo":1,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        },
        {
            "WeekDayGrpNo":2,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        },
        {
            "WeekDayGrpNo":3,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        },
        {
            "WeekDayGrpNo":4,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        },
        {
            "WeekDayGrpNo":5,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        },
        {
            "WeekDayGrpNo":6,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        },
        {
            "WeekDayGrpNo":7,
            "Events":[
                {
                    "ScheduleType":0,
                    "Clock":"06:00:00",
                    "TempFloor":500,
                    "Active":true
                },
                {
                    "ScheduleType":1,
                    "Clock":"09:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":2,
                    "Clock":"12:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":3,
                    "Clock":"13:00:00",
                    "TempFloor":2333,
                    "Active":false
                },
                {
                    "ScheduleType":4,
                    "Clock":"17:00:00",
                    "TempFloor":2777,
                    "Active":false
                },
                {
                    "ScheduleType":5,
                    "Clock":"23:00:00",
                    "TempFloor":2333,
                    "Active":false
                }
            ]
        }
    ],
    "Support":"Wifi Line Voltage Thermostat"
}

Publish 1.1.0

I see that you've updated setup.py for version 1.1.0 but haven't yet published it on PyPI. If you wouldn't mind, could you please do that? I've gotten back to a point where I'd like to pull this into HomeAssistant and finally get my MapeHeat thermostat set up properly.

Much appreciated, thanks for being the Maintainer! :)

Add Energy Usage to the API -> Home Assistant Energy Usage

Wondering Energy usage can be added?

I'm thinking maybe Hourly could be reported downstream to Home Assistant to make NuHeat contribute to the Energy stats for consumption devices in a similar manner to how some smart plugs report energy consumption.

I've done the this work to update the Neurio component, hopefully that will arrive with in HA's 2021.12.1 release. I'd be cool to try to make this work downstream for HA's NuHeat component (though I'm not a native python dev; so might take a while to get merged). :)

Test failure with Python 3.13

=================================== FAILURES ===================================
_______________________ TestThermostat.test_get_data_401 _______________________

self = <tests.test_thermostat.TestThermostat testMethod=test_get_data_401>

    @responses.activate
    def test_get_data_401(self):
        # First request (when initializing the thermostat) is successful
        response_data = load_fixture("thermostat.json")
        responses.add(
            responses.GET,
            config.THERMOSTAT_URL,
            status=200,
            body=json.dumps(response_data),
            content_type="application/json"
        )
    
        # A later, second request throws 401 Unauthorized
        responses.add(
            responses.GET,
            config.THERMOSTAT_URL,
            status=401
        )
    
        # Attempt to reauthenticate
        auth_data = load_fixture("auth_success.json")
        responses.add(
            responses.POST,
            config.AUTH_URL,
            status=200,
            body=json.dumps(auth_data),
            content_type="application/json"
        )
    
        # Third request is successful
        responses.add(
            responses.GET,
            config.THERMOSTAT_URL,
            status=200,
            body=json.dumps(response_data),
            content_type="application/json"
        )
    
        bad_session_id = "my-bad-session"
        good_session_id = auth_data.get("SessionId")
        api = NuHeat(None, None, session_id=bad_session_id)
        serial_number = response_data.get("SerialNumber")
    
        thermostat = NuHeatThermostat(api, serial_number)
>       thermostat.get_data()

tests/test_thermostat.py:206: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
nuheat/thermostat.py:140: in get_data
    data = self._session.request(config.THERMOSTAT_URL, params=params)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <NuHeat username='None'>, url = 'https://www.mynuheat.com/api/thermostat'
method = 'GET', data = None
params = {'serialnumber': '12345', 'sessionid': 'my-bad-session'}, retry = True

    def request(self, url, method="GET", data=None, params=None, retry=True):
        """
        Make a request to the NuHeat API
    
        :param url: The URL to request
        :param method: The type of request to make (GET, POST)
        :param data: Data to be sent along with POST requests
        :param params: Querystring parameters
        :param retry: Attempt to re-authenticate and retry request if necessary
        """
        headers = config.REQUEST_HEADERS
    
        if params and self._session_id:
            params['sessionid'] = self._session_id
    
        if method == "GET":
            response = requests.get(url, headers=headers, params=params)
        elif method == "POST":
            response = requests.post(url, headers=headers, params=params, data=data)
    
        # Handle expired sessions
        if response.status_code == 401 and retry:
>           _LOGGER.warn("NuHeat APIrequest unauthorized [401]. Try to re-authenticate.")
E           AttributeError: 'Logger' object has no attribute 'warn'

nuheat/api.py:78: AttributeError
=========================== short test summary info ============================
FAILED tests/test_thermostat.py::TestThermostat::test_get_data_401 - Attribut...
========================= 1 failed, 35 passed in 0.18s =========================

See also https://bugzilla.redhat.com/show_bug.cgi?id=2252059

requests package pinned too strict, causing Home Assistant unable to upgrade

This library is pinning the requests dependency too strictly.

  install_requires=[
    'requests==2.28.1',
  ],

'requests==2.28.1',

As a result of that, any upstream project using this library, cannot upgrade requests to a newer version. Please ping a range or a minimal version that is required for this library instead.

Context: I ran into this when upgrading the requests package @ Home Assistant to 2.28.2, for which this package caused a conflict.

../Frenck

"Cannot convert float to decimal" when firing simple script

git cloned your project, and created nuheat.py:

from nuheat import NuHeat

# Initalize an API session with your login credentials
api = NuHeat("######", "######")
api.authenticate()

# Fetch a thermostat by serial number / ID. This can be found on the NuHeat website by selecting
# your thermostat and noting the Thermostat ID
thermostat = api.get_thermostat("######")

# Get the current temperature of the thermostat
print thermostat.fahrenheit

The output:

[root@docker python-nuheat]# python nuheat.py
No handlers could be found for logger "nuheat.api"
/usr/lib/python2.6/site-packages/urllib3/util/ssl_.py:339: SNIMissingWarning: An HTTPS request has been made, but the SNI (Subject Name Indication) extension to TLS is not available on this platform. This may cause the server to present an incorrect TLS certificate, which can cause validation failures. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
SNIMissingWarning
/usr/lib/python2.6/site-packages/urllib3/util/ssl_.py:137: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecurePlatformWarning
/usr/lib/python2.6/site-packages/urllib3/util/ssl_.py:137: InsecurePlatformWarning: A true SSLContext object is not available. This prevents urllib3 from configuring SSL appropriately and may cause certain SSL connections to fail. You can upgrade to a newer version of Python to solve this. For more information, see https://urllib3.readthedocs.io/en/latest/advanced-usage.html#ssl-warnings
InsecurePlatformWarning
Traceback (most recent call last):
File "nuheat.py", line 10, in
print thermostat
File "/root/python-nuheat/nuheat/thermostat.py", line 35, in repr
self.fahrenheit,
File "/root/python-nuheat/nuheat/thermostat.py", line 48, in fahrenheit
return nuheat_to_fahrenheit(self.temperature)
File "/root/python-nuheat/nuheat/util.py", line 58, in nuheat_to_fahrenheit
return int(round_half(((nuheat_temperature - 33) / 56.0) + 33))
File "/root/python-nuheat/nuheat/util.py", line 10, in round_half
return Decimal(number).quantize(Decimal("1"), rounding=ROUND_HALF_UP)
File "/usr/lib64/python2.6/decimal.py", line 649, in new
"First convert the float to a string")
TypeError: Cannot convert float to Decimal. First convert the float to a string

Pretty sparse out there for NuHeat API libraries - thanks for working on this. Hoping to eventually query the thermostat and dump its data into my home Grafana instance!

Mape Heat Alternative URL

NuHeat was recently rebranded as Mape Heat and has correspondingly changed their domain name. It seems likely that the API at the new URL is the same as the old one, but registration with new devices under the new brand happens there instead. I believe that old devices will continue to function at the old NuHeat domain.

Old API URL: https://mynuheat.com/api OR https://www.mynuheat.com/api (with optional www subdomain)
New API URL: https://mymapeheat.com/api OR https://www.mymapeheat.com/api (with optional www subdomain)

Since it appears that both URLs should be supported for the time being, it would be ideal if the choice were an option in config.py or taken as an argument to the NuHeat() constructor.

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.