ikalchev / HAP-python

A python implementation of the HomeKit Accessory Protocol (HAP)
Other
618 stars 118 forks source link

Error when constructing HttpBridge #227

Open spmacdonald opened 4 years ago

spmacdonald commented 4 years ago

Hi,

I am trying to follow the Http.py accessory example. This is what I tried:

def get_bridge(driver):
    bridge = HttpBridge('HTTP Bridge', ('', 51111))
    temp_sensor = TemperatureSensor(driver, 'Basement Temperature')
    bridge.add_accessory(temp_sensor)

    return bridge

def main():
    driver = AccessoryDriver(port=51826, persist_file='altadore.state')
    driver.add_accessory(accessory=get_bridge(driver))
    signal.signal(signal.SIGTERM, driver.signal_handler)
    driver.start()

But I get the following Exception:

  File "hap_server.py", line 249, in <module>
    main()
  File "hap_server.py", line 243, in main
    driver.add_accessory(accessory=get_bridge(driver))
  File "hap_server.py", line 234, in get_bridge
    bridge = HttpBridge('HTTP Bridge', ('', 51111))
  File "hap_server.py", line 141, in __init__
    super().__init__(*args, **kwargs)
TypeError: __init__() missing 1 required positional argument: 'display_name'

Versions:

HAP-python==2.7.0 python 3.8.0

For context, what I am trying to do is integrate my konnected.io alarm kit with HomeKit. My plan is to have a server which listens for updates from the konnected board, transform the payload into a message the HttpBridge will understand and POST them to the appropriate location. Is this approach reasonable, or am I missing something obvious?

Thanks a lot for the great project, I have enjoyed working with it.

Scott

Pythonaire commented 4 years ago

HttpBridge('HTTP Bridge', ('', 51111)) --> call a Python class. Didn't find a class "HttpBridge". Do you mean the class "Bridge"?

spmacdonald commented 4 years ago

No I mean HttpBridge as defined here: https://github.com/ikalchev/HAP-python/blob/dev/accessories/Http.py#L79

What I want to do is POST data and update the Accessory state. I thought that was the purpose of the Http.py example but I cannot figure out how to get it running due to the error above.

If there is a more straightforward way to forward data from an external service and update the accessory state that way please let me know.

Thanks Scott

Pythonaire commented 4 years ago

Ok sorry, i see. The "HttpBridge" handover @type address: tuple(str, int)(init line 135) , but str is blank ... is that right? More straightforward might be using of "request" and "json". I have external devices (sensor devices) connected via 433 MHz packet transceiver. You can do the same with your http binded device. My sensor device send the values in a json-like format. If data comes in, the script converts the string with "json", extract the values and store them into a global variable (better then "pickle"). A second asynchronous function pull these data to the HAP characteristic. If you like, see my HAP-Python-Packet-Radio The "Transceiver.py" handle incoming data. The "Sensor.py" converts the data into HAP characteristics.

Good luck

spmacdonald commented 4 years ago

I tried blank and also 0.0.0.0.

I guess what you suggest would work but I would rather not resort to passing around global variables.

The other problem with that approach is you are polling, I want to push the updates as they come in. It is for an alarm system.

Pythonaire commented 4 years ago

no, its not polling. The external device has a definition, then it should send data. In your case, it could be a alarm. The incoming data will triggered by an GPIO event. I do this, because the original code loop permanently (see "accessory.py", def run_at_interval). This can push the cpu usage up to 100%. If you want to put both things together (receive data/alarm and send to the HomeKit), just put both things in one function.

Just for explanation: My device goes into deep sleep mode after measuring and sending data. Tapping on the device symbol in the HomeKit App or refreshing the App, starts a request to the device, but it is sleeping.That's why I store the actually/last measured value into a global variable. Other people do that with "python pickle". But it is storing in a physical file. In this case, a power failure or bad disk can leads into crash.

Pythonaire commented 4 years ago

this works so fare:

!/usr/bin/env python3

import logging, signal from pyhap.accessory import Accessory from HttpAccessory import HttpBridge, HttpBridgeHandler from pyhap.accessory_driver import AccessoryDriver from Actors import HTTPSwitch

logging.basicConfig(level=logging.INFO, format="[%(module)s] %(message)s")

def get_bridge(driver): http_bridge = HttpBridge(driver=driver,display_name="HTTP Bridge", address=("", 51111)) http_bridge.add_accessory(HTTPSwitch(driver, 'MySwitch')) return http_bridge

driver = AccessoryDriver(port=51826, persist_file='http.state') driver.add_accessory(accessory=get_bridge(driver)) signal.signal(signal.SIGTERM, driver.signal_handler) driver.start()