Using virtual lightbulbs to represent solar stats in HomeKit
Homebridge has been an amazing contribution to connecting most of my home into a single automation platform.
If you’ve read this blog you’ll know that I’ve electrified my home and dumped fossil gas into the past where it belongs.
Bringing solar into HomeKit
Part of electrifying my home was adding solar and I’ve talked about how I’ve extracted data from my realtime circuit hardware via a dashboard created with a magtag device on my fridge. But I wanted to bring it into HomeKit so I could run automations based on my solar generation.
Possible automation ideas
Here are some automation ideas I want to explore or have done already:
- Increase heat temp on ducted aircon when solar is exporting above a certain amount
- Decrease heat temp when I start pulling a certain amount from the grid
- Charge electric car when I am exporting power
- Stop charging car when I start pulling too much from the grid
- Monitor wholesale export price and maximise possible exports, solar + home battery only makes sense for this
- And many more
At the moment Australia has an export feed in tariff (FiT) anywhere from 12c - 6.7c depending on where you live, how big your system is and what retailer you use. This is decreasing yearly so being able to have my house automated to maximise using power generated onsite will be more advantageous in the coming years.
How do we represent solar in HomeKit?
If the title didn’t give it away its lightbulbs! I’ve split my solar into 4 light bulbs:
- Grid - Data if I’m pulling power from the grid
- House - How much power the house is using
- Export - If and how much I’m exporting
- Production - How much electricity am I generating
Lights are perfect for solar as they can have 3 aspects that fit very well with solar:
- on/off - Am I exporting, importing etc
- Lux aka ambient brightness - I use this value to represent Watts e.g. 1500 lux = 1.5kW
- Brightness - Represents percentage of mix e.g. 36% on the grid light means I’m pulling 36% of my houses energy needs from the grid
But how…
So how do I get lightbulbs in HomeKit and how do I get their various states to represent the data?
Homebridge has a great plugin called cmd4, it allows you to connect cli scripts with HomeKit accessories so when I set up a lightbulb in cmd4 I can tell it to run a bash script and using cmd4s polling abilities it can query those states however often I need, in my case once every minute.
{
"type": "Lightbulb",
"name": "Exporting",
"brightness": 0,
"state_cmd": "bash /path/to/export.sh",
"polling": [
{
"characteristic": "brightness",
"interval": 60,
"timeout": 5000
},
{
"characteristic": "on",
"interval": 60,
"timeout": 5000
}
],
"linkedTypes": [
{
"type": "LightSensor",
"name": "Export kW",
"currentAmbientLightLevel": 0,
"state_cmd": "bash /path/to/export.sh",
"polling": [
{
"characteristic": "currentAmbientLightLevel",
"interval": 60,
"timeout": 5000
}
]
}
]
}
Cmd4 plugin will then call the script with a few arguments based on which characteristic it is querying or setting data for, in our case the lightbulbs are read only.
bash script.sh Get “Export kW” CurrentAmbientLightLevel
This is controlled by the polling array in the plugin config and allows you to target specific characteristics e.g. on/off, brightness and currentAmbientLightLevel in my case.
In my bash script I have it curl out to a cloudflare worker with basic auth applied to then query my solar stats, weather data and sunrise/sunset apis.
if [ "${io}" == "Get" ]; then
case $characteristic in
'Brightness')
curl -s https://worker.accountname.workers.dev -H ‘Authorization: password1’ | jq '.pUtilisation'
exit 0
;;
'CurrentAmbientLightLevel')
curl -s https://worker.accountname.workers.dev -H 'Authorization: password1' | jq '.generated'
exit 0
;;
'On')
echo $(curl -s https://worker.accountname.workers.dev -H 'Authorization: password1' | jq '.on')
exit 0
;;
*)
printf "UnHandled Get ${device} Characteristic ${characteristic}\n"
exit -1
;;
esac
fi
Once the script curls for the response I utilise jq to extract the value from the json response and return that to homebridge to forward to HomeKit.
Using workers made it much easier to keep my credentials secure by utilising encrypted env variables so all I have to do is rotate my basic auth if that is compromised. It also allows me to extend and massage the data coming back into an efficient format that just allows cmd4 to read the values and not have to do calculations etc.
Automations
With solar in HomeKit I can now setup automations I can check when the Export kW lux increases or decreases below certain levels and also check weather data so it can make the call to increase or decrease my heater during colder months.
The feels like temp is a better one to work my automations off as this “feels” more accurate. The internal thermostat of the aircon itself will actually make the call as to when to turn the unit on too.
For my heating boost automation it would check the following:
- Check the lux value is >= 1,500 lux of export lightbulb
- Make sure the feels like outside temp is <= 14C
For whatever reason the Home app has very limited controls when setting automations so in order to accomplish this specific automation I had to create it in the Eve app which exposes more granular controls when creating an automation. HomeKit is capable of this its just that the apple apps don’t expose it, hopefully iOS16 and macOS Ventura fix this.
Next steps
I plan to look into dummy switches and/or home assistant to get better control and priority around which automation should win in the case of a conflict e.g. my heater could turn up and my car could start charging which might make power start coming from the grid which would turn both off and then it could keep flip flopping between the 2 states.
I also plan to explore forcast.solar to start automations based on predictions of potential output, that way I can make forward decisions based on the predictions available.