pihome-shc / pihome

PiHome - Smart Heating, Ventilation and Air Conditioning (HVAC)
http://www.pihome.eu
Other
55 stars 25 forks source link

iOS HomeKit API - Homebridge #193

Open pihome-shc opened 4 years ago

pihome-shc commented 4 years ago

Homebridge is a lightweight NodeJS server that emulates the iOS HomeKit API. This would be good add-on for PiHome if we can get this one working with PiHome.

Help and Reference:

dvdcut commented 4 years ago

@pihome-shc i have installed Homebridge with webgui now what is next? is there any process to read temperature or show temperature on apple devices?

twa127 commented 4 years ago

I'm at the same point, I guess what we need to decide is what we want to achieve eg do the same as with Echo or more?

I installed https://www.npmjs.com/package/homebridge-dummy plugin which at least demonstrates a dummy switch and this one could possibly a basis for talking to pihome server https://github.com/Supereg/homebridge-http-switch

dvdcut commented 4 years ago

@twa127 question on echo: can we add another option to read temperature ? like alexa what is the temperature for (zone name) ?

i think all these compatibility device should have same options. i mean from apple home kit we can not control schedule or anything but boost only ? display temperature with zone name ? or you are thinking adding more options? i m still trying to understand how Homebridge works and youtube only talks about all commercial solutions and add them but nothing about custom solution or adding your own stuff.

twa127 commented 4 years ago

With Echo we are emulating a WeMo switch which only responds to ON and OFF and returns a boolean reflecting the state of the switch. For temperature we would need something else but I guess that must be possible.

Custom solutions are possible like the dummy switch, just need you to construct the index.js and package.json code, the functionality is in index.js

twa127 commented 4 years ago

It would not take much to turn the dummy switch code in to a Boost control, node.js has a mysql module so we could update the boost status value depending if the switch were ON or OFF

pihome-shc commented 4 years ago

Adding to read temperature for any zone would be good addition on echo but so far i m very happy with the work @twa127 have done. as far as Homebridge goes it would be zone icons with zone name and if tape on zone button it turn on boost for that zone. i dont think more can be achieved and i dont own any commercial solution to experiment with or what commercial or non commercial solutions can do in homekit.

my knowledge is very limited on python and next to nothing on node.js but may be its time to upskill myself.

ps: this lockdown is killing me getting home sick now :(

twa127 commented 4 years ago

Let’s hope we all keep well.

I’ve been looking at Philips Hue as we could get temperature back, early days :-)

Still playing with homebridge

Sent from my iPhone

On 2 Apr 2020, at 22:20, PiHomeHVAC notifications@github.com wrote:

 Adding to read temperature for any zone would be good addition on echo but so far i m very happy with the work @twa127 have done. as far as Homebridge goes it would be zone icons with zone name and if tape on zone button it turn on boost for that zone. i dont think more can be achieved and i dont own any commercial solution to experiment with or what commercial or non commercial solutions can do in homekit.

my knowledge is very limited on python and next to nothing on node.js but may be its time to upskill myself.

ps: this lockdown is killing me getting home sick now :(

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

dvdcut commented 4 years ago

@twa127 can i help in anyway?

twa127 commented 4 years ago

thanks for the offer, I'll let you know when i get my head around it all :-)

twa127 commented 4 years ago

I've got something working for me using the HTTP Switch example and a bit of python acting as the response server. Still a work in progress :-))

  1. sudo pip install flask request
  2. sudo npm install -g homebridge-http-switch
  3. edit /var/lib/homebridge/config.json and replace the accessories section with the one in the attached zip, you will need to change the zone names in the urls to match your config. You can add extra switches as required, remember the comma between each accessory section
  4. run the response server with 'python homekit_api.py' this can run as a service later after testing

homekit_api.zip

pihome-shc commented 4 years ago

@twa127 that is fantastic work.

pihome-shc commented 4 years ago

@twa127, great work, good thinking to run python script as service also can we add this under setting->services, any option we can auto generate accessories list from all exiting zone,

twa127 commented 4 years ago

I had the same thought about something to add the accessories based on the zones, I'll work on that, perhaps make it part of the install shell.

Comitted the change to add the API to the services list

pihome-shc commented 4 years ago

@twa127 here are results of new install script, but if i manually run python config_json.py then it updates accessories.


root@pihome:/var/www/homekit# systemctl stop pihome_homekit_api.service
root@pihome:/var/www/homekit# sh ./install_homekit.sh
Checking if python-requests is Installed
python-requests already installed
Checking if python-flask is Installed
python-flask already installed
Checking For Existing Unit File
Deleting Existing Unit File: /lib/systemd/system/pihome_homekit_api.service
Creating Unit File: /lib/systemd/system/pihome_homekit_api.service
Enabling the service
Starting the service
./install_homekit.sh: 70: ./install_homekit.sh: Syntax error: Unterminated quoted string
pihome-shc commented 4 years ago

@twa127 at line 67 missing "

twa127 commented 4 years ago

Oops committed the fix

Sent from my iPhone

On 6 Apr 2020, at 18:34, PiHomeHVAC notifications@github.com wrote:

 @twa127 at line 67 missing "

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

twa127 commented 4 years ago

Hi,

I've added getTemperature to the homekit api so that you can get the temperature for any zone and use in hombridge. You need to install the homebridge-http-temperature-sensor plugin and add a new accessory to the homebridge config eg

    {
        "accessory": "HTTP-TEMPERATURE",
        "name": "Ground Floor",
        "pullInterval": "1000",
        "getUrl": {
            "url": "http://localhost:8081/api/getTemperature?zonename=Ground Floor",
            "method": "GET"
        }
    },

Choose your zone name and use in the url, you can add for as many zones as you like and then setup rooms on your iOS device

pihome-shc commented 4 years ago

@twa127 after updating and installing, i have two icons for each zone and its not showing temperature for any zone.

twa127 commented 4 years ago

Hi

Did you change config.jason to match your zone names?

Sent from my iPhone

On 8 Apr 2020, at 00:16, PiHomeHVAC notifications@github.com wrote:

 @twa127 after updating and installing, i have two icons for each zone and its not showing temperature for any zone.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or unsubscribe.

pihome-shc commented 4 years ago

@twa127 here is my accessories config.

    "accessories": [
        {
            "name": "Ground Floor",
            "pullInterval": "1000",
            "accessory": "HTTP-SWITCH",
            "statusUrl": {
                "url": "http://localhost:8081/api/switchStatus?zonename=Ground Floor",
                "method": "GET"
            },
            "switchType": "stateful",
            "onUrl": {
                "url": "http://localhost:8081/api/switchOn?zonename=Ground Floor",
                "method": "GET"
            },
            "offUrl": {
                "url": "http://localhost:8081/api/switchOff?zonename=Ground Floor",
                "method": "GET"
            }
        },
        {
            "name": "First Floor",
            "pullInterval": "1000",
            "accessory": "HTTP-SWITCH",
            "statusUrl": {
                "url": "http://localhost:8081/api/switchStatus?zonename=First Floor",
                "method": "GET"
            },
            "switchType": "stateful",
            "onUrl": {
                "url": "http://localhost:8081/api/switchOn?zonename=First Floor",
                "method": "GET"
            },
            "offUrl": {
                "url": "http://localhost:8081/api/switchOff?zonename=First Floor",
                "method": "GET"
            }
        },
        {
            "name": "Hot Water",
            "pullInterval": "1000",
            "accessory": "HTTP-SWITCH",
            "statusUrl": {
                "url": "http://localhost:8081/api/switchStatus?zonename=Hot Water",
                "method": "GET"
            },
            "switchType": "stateful",
            "onUrl": {
                "url": "http://localhost:8081/api/switchOn?zonename=Hot Water",
                "method": "GET"
            },
            "offUrl": {
                "url": "http://localhost:8081/api/switchOff?zonename=Hot Water",
                "method": "GET"
            }
        },
        {
            "accessory": "HTTP-TEMPERATURE",
            "name": "Ground Floor",
            "pullInterval": "1000",
            "getUrl": {
                "url": "http://localhost:8081/api/getTemperature?zonename=Ground Floor",
                "method": "GET"
            }
        },
        {
            "accessory": "HTTP-TEMPERATURE",
            "name": "First Floor",
            "pullInterval": "1000",
            "getUrl": {
                "url": "http://localhost:8081/api/getTemperature?zonename=First Floor",
                "method": "GET"
            }
        },
        {
            "accessory": "HTTP-TEMPERATURE",
            "name": "Hot Water",
            "pullInterval": "1000",
            "getUrl": {
                "url": "http://localhost:8081/api/getTemperature?zonename=Hot Water",
                "method": "GET"
            }
        }
    ],
twa127 commented 4 years ago

Looks okay to me, the only thing I'm doing different is that I've got the temperature sensors all before the switches.

twa127 commented 4 years ago

Mine-

"accessories": [
    {
        "accessory": "HTTP-TEMPERATURE",
        "name": "Ground Floor",
        "pullInterval": "1000",
        "getUrl": {
            "url": "http://localhost:8081/api/getTemperature?zonename=Ground Floor",
            "method": "GET"
        }
    },
    {
        "accessory": "HTTP-TEMPERATURE",
        "name": "Lounge",
        "pullInterval": "1000",
        "getUrl": {
            "url": "http://localhost:8081/api/getTemperature?zonename=Lounge",
            "method": "GET"
        }
    },
    {
        "accessory": "HTTP-SWITCH",
        "name": "Hot Water",
        "switchType": "stateful",
        "pullInterval": "1000",
        "onUrl": {
            "url": "http://localhost:8081/api/switchOn?zonename=Ch. Hot Water",
            "method": "GET"
        },
        "offUrl": {
            "url": "http://localhost:8081/api/switchOff?zonename=Ch. Hot Water",
            "method": "GET"
        },
        "statusUrl": {
            "url": "http://localhost:8081/api/switchStatus?zonename=Ch. Hot Water",
            "method": "GET"
        }
    },
    {
        "accessory": "HTTP-SWITCH",
        "name": "Central Heating",
        "switchType": "stateful",
        "pullInterval": "1000",
        "onUrl": {
            "url": "http://localhost:8081/api/switchOn?zonename=Ground Floor",
            "method": "GET"
        },
        "offUrl": {
            "url": "http://localhost:8081/api/switchOff?zonename=Ground Floor",
            "method": "GET"
        },
        "statusUrl": {
            "url": "http://localhost:8081/api/switchStatus?zonename=Ground Floor",
            "method": "GET"
        }
    }
],
twa127 commented 4 years ago

Hi,

I think I've managed to simplify the API interface by dumping all the python and replacing it with PHP, this way we don't have to run any additional service.

Can you please try the attached, it all sits in /var/www/api the install.sh will remove the existing python service, modify the existing config.json to replace localhost:8081 with simply 127.0.0.1 and add a block to /etc/apache2/sites-available/000-default.conf to enable use of the URL without the .php suffix

Please let me know what you think api.zip

twa127 commented 4 years ago

oops error in the install.sh I forgot to change 000-default.conf modification after using a test directory, the attached is fixed. install.zip

pihome-shc commented 4 years ago

@twa127 that worked perfectly, can you combine temperature zone icon

twa127 commented 4 years ago

how do you mean, combine temperature zone icon?

pihome-shc commented 4 years ago

@twa127, yes

twa127 commented 4 years ago

sorry not sure what you mean

pihome-shc commented 4 years ago

@twa127 like we have temperature reading and zone on PiHome web interface, can we achive the same for homekit? right now i have two icons for each zone.

twa127 commented 4 years ago

ah I see, I think maybe not as one is a switch and the other a sensor, but I'll investigate

pihome-shc commented 4 years ago

forget to add the logs for install.sh, i think backup 000-default.conf have some error but apart from that all worked.

root@pihome:/var/www/api# sh ./install.sh
Checking For Existing Unit File
Stopping the service
Disabling the service
Removed /etc/systemd/system/multi-user.target.wants/pihome_homekit_api.service.
Deleting Existing Unit File: /lib/systemd/system/pihome_homekit_api.service
Enabling mod_rewrite
Enabling module rewrite.
To activate the new configuration, you need to run:
  systemctl restart apache2
Backing Up and Modifying /etc/apache2/sites-available/000-default.conf
cp: missing destination file operand after '/etc/apache2/sites-available/000-def                                                                                                             ault.conf{,-20200409-215325}'
Try 'cp --help' for more information.
Restarting the apache service
Backing Up and Updateing /var/lib/homebridge/config.json
cp: missing destination file operand after '/var/lib/homebridge/config.json{,-20                                                                                                             200409-215326}'
Try 'cp --help' for more information.
Restarting Homebridge
ℹ Restarting Homebridge Service
ℹ Restarting Homebridge Service...
✔ Homebridge Restarted
root@pihome:/var/www/api#
twa127 commented 4 years ago

hi

did you execute as bash install.sh, the cp format I used is bash specific

pihome-shc commented 4 years ago

@twa127 yes, on same note should we move these 3rd Party related stuff on in another folder and also make some standard for voice and homekit etc?

pihome-shc commented 4 years ago

on one icon with temperature reading and zone name, just came across this link,

https://blog.encoredevlabs.com/feature/thermostat/raspberrypi/home-automation/homekit/homebridge/2017/12/25/homekit-pi-thermostat.html

twa127 commented 4 years ago

The reason I put it in /var/www/api was so that it conformed to the example config.json

I'll have a look at that link, my thoughts were that the main use for this is with Siri so the visual side was less important, the way I'm using it is I've setup rooms which kind of map to zones and each room can have a switch and/or a sensor

twa127 commented 4 years ago

That looks interesting, we currently have a boost switch and temperature sensor, I guess this would be a third accessory which is a zone controller

twa127 commented 4 years ago

Hi,

I think I can get a thermostat plugin working with PiHome using the same method as with the switch and sensor, just need to work on the API, I'll get back to you

pihome-shc commented 4 years ago

that link is of one zone US HVAC system (apparently they have only one zone in every house). i think zone name with temperature would be good if possible but if its to much work then i would say leave it as they are, love that api idea (my python knowledge is next to nothing) so understanding php ie easy for me :) i haven't tried voice (siri) i was just using gui part of it.

twa127 commented 4 years ago

I was thinking the same as you, that thermostat model does not really work for PiHome as things are built around schedules. I could make it work as a boost switch but the interface might be a little confusing as the 'Cool' and 'Auto' buttons would not be relevant and I can't see a way of changing the design

twa127 commented 4 years ago

I have left the switches in the default room so 'hey siri hot water on' works okay, the sensors are allocated to rooms, so 'hey siri lounge' comes back with the temp

pihome-shc commented 4 years ago

@twa127 after updating i m getting following errors.

[4/12/2020, 00:04:21] [Ground Floor] Error occurred while pulling update from switch: Got html error code 404
[4/12/2020, 00:04:21] [Hot Water] getStatus() http request returned http error code: 404
[4/12/2020, 00:04:21] [Hot Water] Error occurred while pulling update from switch: Got html error code 404
[4/12/2020, 00:04:21] [First Floor] getStatus() http request returned http error code: 404
[4/12/2020, 00:04:21] [First Floor] Error occurred while pulling update from switch: Got html error code 404
[4/12/2020, 00:04:24] [First Floor] getTemperature() returned http error: 404
pihome-shc commented 4 years ago

after adding .htaccess file everything works ok.

twa127 commented 4 years ago

oops don't know how I forgot that one :-(

dvdcut commented 4 years ago

hi, good to see homebridge working, actually interaction with pihome over voice is very good and now i can say it is classed better then all commercial solutions. since @twa127 moved to php it mean i can pock around to get more features added voice. also may be best to have some standard or api built to interact with pihome to make it compatible with other iot devices out there. @twa127 your knowledge of programing is way way better then mine.

twa127 commented 4 years ago

Hi,

I was thinking that another approach for homekit would be a PiHome platform rather than multiple HTTP accessories. I've been looking at https://www.npmjs.com/package/homebridge-http-webhooks and have produced a cut down version with just switch, sensor and thermostat accessories. This could dispense with using APIs and polling for changes, but still struggling to understand how best to interface it to the database

pihome-shc commented 4 years ago

@twa127 what looks very interesting way to connect to homebridge, right now PiHome does not have any api and can not be queried by any external application, as @dvdcut said may be its time to implement some sort of api and where any application can interact with PiHome (not only read but write as well information).

@dvdcut welcome back, how you feeling?

twa127 commented 4 years ago

Hi,

you can query the zone temperature from any browser using for example http://pihome server ip/api/getTemperature?zonename=Lounge same for switchStatus?zonename=Lounge and .../api/switchOn?zonename=Lounge and .../switchOff?zonename=Lounge

So any app could access PiHome using those Urls

pihome-shc commented 4 years ago

@twa127 that is very good, i m working on PiConnect and response is all based on Jason as well to and from client.

twa127 commented 4 years ago

Hi,

I've now got the webhook version to work, the main advantages are that it could be installed as a single homekit package and that it would lighten the load on the controller. The current version is polling the zone state and temperature every 5 seconds, in most instances the value have not changed so no action is required. The webhook version uses the boiler cron job to check if either/or the zone state or temperature have changed and only updates homekit if there has been a change, hence less CPU load.

I've produced a cut down version of homebridge-http-webhooks which only has the stateful switch, the temperature sensor and the thermostat (included just in case we find a use for it). The config.json would have no accessories section and a platform which looked something like this

    {
        "platform": "HttpPiHome",
        "webhook_port": "51828",
        "cache_directory": "./.node-persist/storage",
        "switches": [
            {
                "id": "switch39",
                "name": "Hot Water Zone",
                "on_url": "http://127.0.0.1/api/switchSet?zonename=Hot Water&state=1",
                "on_method": "GET",
                "off_url": "http://127.0.0.1/api/switchSet?zonename=Hot Water&state=0",
                "off_method": "GET"
            },
            {
                "id": "switch38",
                "name": "Lounge Zone",
                "on_url": "http://127.0.0.1/api/switchSet?zonename=Lounge&state=1",
                "on_method": "GET",
                "off_url": "http://127.0.0.1/api/switchSet?zonename=Lounge&state=0",
                "off_method": "GET"
            }
        ],
        "sensors": [
            {
                "id": "sensor38",
                "name": "Hot Water Temperature"
            },
            {
                "id": "sensor39",
                "name": "Lounge Temperature"
            }
        ]
    }

We would only have one API switchSet which would take the zonename and state (1 or 0), the rest would be done through the webhook api, any other app can use the APIs and the result is formatted as JSON, for example APIs are -

Get temperature for zone with id = 38 - http://ip address:51828/?accessoryId=sensor38 Set temperature for zone with id = 38 - http://ip address:51828/?accessoryId=sensor38&value=19.5 Get controller state for zone with id = 38 - http://ip address:51828/?accessoryId=switch38 Set controller state to ON for zone with id = 38 - http://ip address:51828/?accessoryId=switch38&state=true

What do you think, stick with the multiple accessories or go for the PiHome platform?

pihome-shc commented 4 years ago

@twa127, i think PiHome platform option would be better, and you are right with current code it generated lots of read which can kill sd cards in rpi.