Skip to content

Commit

Permalink
Added config flow, code optimizations
Browse files Browse the repository at this point in the history
  • Loading branch information
valentinfrlch committed May 17, 2024
1 parent 8c6ce41 commit 0dffb57
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 22 deletions.
53 changes: 32 additions & 21 deletions custom_components/gpt4vision/__init__.py
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
# Declare variables
from .const import DOMAIN, CONF_API_KEY, CONF_MAXTOKENS, CONF_TARGET_WIDTH, CONF_MODEL, CONF_MESSAGE, CONF_IMAGE_FILE
import base64
import requests
import io
import os
from homeassistant.core import SupportsResponse
from homeassistant.exceptions import ServiceValidationError
from PIL import Image

DOMAIN = 'gpt4vision'

# config
CONF_API = 'api'
CONF_MAXTOKENS = 'max_tokens'
CONF_TARGET_WIDTH = 'target_width'
CONF_MODEL = 'model'
CONF_MESSAGE = 'message'
CONF_IMAGE_FILE = 'image_file'
CON_RESPONSE_FILE_PATH = '/config/custom_components/gpt4vision/'
async def async_setup_entry(hass, entry):
"""Set up gpt4vision from a config entry."""
# Get the API key from the configuration entry
api_key = entry.data[CONF_API_KEY]

# Store the API key in hass.data
hass.data[DOMAIN] = {
"api_key": api_key
}

return True


def setup(hass, config):
Expand All @@ -26,15 +30,13 @@ def image_analyzer(data_call):
json: response_text
"""

# Read api key from configuration.yaml
try:
api_key = str(config[DOMAIN][CONF_API])
except KeyError:
raise ServiceValidationError("API key is missing. Please check your configuration.yaml file.")

# Try to get the API key from hass.data
api_key = hass.data.get(DOMAIN, {}).get("api_key")

# Check if api key is present
if not api_key:
raise ServiceValidationError("API key is missing. Please check your configuration.yaml file.")
raise ServiceValidationError(
"API key is required. Please set up the integration again.")

# Read data from service call
# Resolution (width only) of the image. Example: 1280 for 720p etc.
Expand All @@ -48,6 +50,11 @@ def image_analyzer(data_call):
# Message to be sent to AI model
message = str(data_call.data.get(CONF_MESSAGE)[0:2000])

# Check if image file exists
if not os.path.exists(image_path):
raise ServiceValidationError(
f"Image does not exist: {image_path}")

def encode_image(image_path):
"""Encode image as base64
Expand All @@ -57,6 +64,7 @@ def encode_image(image_path):
Returns:
string: image encoded as base64
"""

# Open the image file
with Image.open(image_path) as img:
width, height = img.size
Expand Down Expand Up @@ -90,13 +98,16 @@ def encode_image(image_path):
{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}]}], "max_tokens": max_tokens}

# Get response from OpenAI and read content inside message
response = requests.post("https://api.openai.com/v1/chat/completions", headers=headers, json=data)

response = requests.post(
"https://api.openai.com/v1/chat/completions", headers=headers, json=data)

# Check if response is successful
if response.status_code != 200:
raise ServiceValidationError(response.json().get('error').get('message'))

response_text = response.json().get("choices")[0].get("message").get("content")
raise ServiceValidationError(
response.json().get('error').get('message'))

response_text = response.json().get(
"choices")[0].get("message").get("content")
return {"response_text": response_text}

hass.services.register(
Expand Down
22 changes: 22 additions & 0 deletions custom_components/gpt4vision/config_flow.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
from homeassistant import config_entries
from .const import DOMAIN, CONF_API_KEY
import voluptuous as vol


class gpt4visionConfigFlow(config_entries.ConfigFlow, domain=DOMAIN):
VERSION = 1

async def async_step_user(self, user_input=None):
data_schema = vol.Schema({
vol.Required(CONF_API_KEY): str
})

if user_input is not None:
# Save the API key
return self.async_create_entry(title="GPT4Vision Configuration", data=user_input)

return self.async_show_form(
step_id="user",
data_schema=data_schema,
description_placeholders=user_input
)
9 changes: 9 additions & 0 deletions custom_components/gpt4vision/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
""" Constants for gpt4vision component"""

DOMAIN = "gpt4vision"
CONF_API_KEY = 'api_key'
CONF_MAXTOKENS = 'max_tokens'
CONF_TARGET_WIDTH = 'target_width'
CONF_MODEL = 'model'
CONF_MESSAGE = 'message'
CONF_IMAGE_FILE = 'image_file'
3 changes: 2 additions & 1 deletion custom_components/gpt4vision/manifest.json
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
{
"domain": "gpt4vision",
"name": "GPT-4 vision",
"config_flow": true,
"codeowners": ["@valentinfrlch"],
"issue_tracker": "https://github.com/valentinfrlch/ha-gpt4vision/issues",
"documentation": "https://github.com/valentinfrlch/ha-gpt4vision",
"iot_class": "cloud_polling",
"version": "0.1.4"
"version": "0.2.0"
}
13 changes: 13 additions & 0 deletions custom_components/gpt4vision/translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"title": "Add API key",
"description": "Provide your API key. See docs for more information.",
"data": {
"api_key": "Your API key"
}
}
}
}
}
13 changes: 13 additions & 0 deletions strings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"config": {
"step": {
"user": {
"title": "Add API key",
"description": "Provide your API key. See docs for more information.",
"data": {
"api_key": "Your API key"
}
}
}
}
}

0 comments on commit 0dffb57

Please sign in to comment.