Skip to content

Commit

Permalink
Version 0.22.0 (Beta 22.0)
Browse files Browse the repository at this point in the history
* **NOTE** As stated earlier, the entire HomeKit engine is being
optimized and rewritten for various reasons.  There is a new plugin
configuration option that allows you to revert to the previous method
if the new method is causing problem, but this is on a
release-by-release basis, meaning that only changes in **this** release
will roll back to using the old methods, the next release will not be
able to roll back anything from this release.  The functions impacted
will be noted in the release notes as 'Library Change'.  Please report
any issues that are caused by the new library that are resolved by
returning to the old methods.
* Added error trapping around building the camera configuration in case
there's an odd setup that may cause the camera build to fail it will
not impact the rest of the homekit devices
* Added new action under device actions to [restart an individual
server](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#
restart-accessory-server)
* Added new action in the action root to [restart all running
servers](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions
#restart-all-accessory-servers)
* Added new action under device actions to [force a HomeKit refresh for
a
device](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#
force-homekit-refresh) - this may help with [Issue
#87](#87)
* Added new action in the action root to [force a HomeKit refresh for
all devices on a
server](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#
force-homekit-refresh-on-all-items)
* Library Change: Added minimum and maximum values to the API payload
so Homebridge can dynamically change the ranges as needed -
particularly in situations where the built-in ranges were incorrect,
such as temperature values that couldn't go below 50F or above 100F.
* Library Change: Optimized API payload processing method, API calls
will only return what Homebridge wants with no extra fields and does it
far more efficiently
* Library Change: Moved API payload processing to new factory package
* Library Change: Experimental change to not wait for commands to run -
this may be restored in the next release but I believe waiting is
unnecessary because HomeKit will be updated when the command completes
anyway, the benefit of this is faster response (and if you use slow
devices like curtain controls it will prevent Siri from saying 'some of
your devices are not responding')
* Library Change: Started adding the underlying structure to test the
_possibility_ of using Indigo variables as HomeKit devices
* Library Change: Cache HomeKit devices and update dynamically,
improved API performance by 600%
  • Loading branch information
Colorado Four Wheeler authored and Colorado Four Wheeler committed Apr 2, 2018
1 parent fd695f8 commit f079678
Show file tree
Hide file tree
Showing 27 changed files with 1,014 additions and 226 deletions.
23 changes: 19 additions & 4 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
Release Notes
==========

Version 0.21.0 (Beta 21.0)
Version 0.22.0 (Beta 22.0)
==========
* **NOTE** As stated earlier, the entire HomeKit engine is being optimized and rewritten for various reasons. There is a new plugin configuration option that allows you to revert to the previous method if the new method is causing problem, but this is on a release-by-release basis, meaning that only changes in **this** release will roll back to using the old methods, the next release will not be able to roll back anything from this release. The functions impacted will be noted in the release notes as 'Library Change'. Please report any issues that are caused by the new library that are resolved by returning to the old methods.
* Added error trapping around building the camera configuration in case there's an odd setup that may cause the camera build to fail it will not impact the rest of the homekit devices
* Added new action under device actions to [restart an individual server](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#restart-accessory-server)
* Added new action in the action root to [restart all running servers](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#restart-all-accessory-servers)
* Added new action under device actions to [force a HomeKit refresh for a device](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#force-homekit-refresh) - this may help with [Issue #87](https://github.com/Colorado4Wheeler/HomeKit-Bridge/issues/87)
* Added new action in the action root to [force a HomeKit refresh for all devices on a server](https://github.com/Colorado4Wheeler/HomeKit-Bridge/wiki/Actions#force-homekit-refresh-on-all-items)
* Library Change: Added minimum and maximum values to the API payload so Homebridge can dynamically change the ranges as needed - particularly in situations where the built-in ranges were incorrect, such as temperature values that couldn't go below 50F or above 100F.
* Library Change: Optimized API payload processing method, API calls will only return what Homebridge wants with no extra fields and does it far more efficiently
* Library Change: Moved API payload processing to new factory package
* Library Change: Experimental change to not wait for commands to run - this may be restored in the next release but I believe waiting is unnecessary because HomeKit will be updated when the command completes anyway, the benefit of this is faster response (and if you use slow devices like curtain controls it will prevent Siri from saying 'some of your devices are not responding')
* Library Change: Started adding the underlying structure to test the _possibility_ of using Indigo variables as HomeKit devices
* Library Change: Cache HomeKit devices and update dynamically, improved API performance by 600%

Previous Release Notes
==========

Version 0.21.0 (Beta 21.0)
---------------
* **NOTE** This release begins the process of rewriting the entire HomeKit integration, small chunks at a time, so it's possible that this can break things. I'm trying to thoroughly test changes to make sure the end result is the same, but you have been warned.
* Added failsafe when saving the Homebridge configuration that if there are no Indigo devices being passed that the Homebridge-indigo2 platform will not be loaded, this in case you are using a "camera server" that has nothing else on it doesn't cause issues with Homebridge-Indigo2 trying to load zero accessories
* Changed model:submodel device resolution to detect if either model or submodel is an empty attribute and not pass the ":" separator if that is the case
* Completely rewrote the SecuritySpy URL construction routine to better support users who don't store the xpassword state ([Issue #81](https://github.com/Colorado4Wheeler/HomeKit-Bridge/issues/81))
* Moved model/firmware resolution out of the main plugin and into the new factory package
* Code housekeeping and cleanup

Previous Release Notes
==========

Version 0.20.1 (Beta 20.1)
---------------
* Added additional sanity check on SecuritySpy servers that if they don't have the xaddress populated to get the address from a different field ([Issue #81](https://github.com/Colorado4Wheeler/HomeKit-Bridge/issues/81))
Expand Down
2 changes: 1 addition & 1 deletion EPS HomeKit Bridge.indigoPlugin/Contents/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>PluginVersion</key>
<string>0.21.0</string>
<string>0.22.0</string>
<key>ServerApiVersion</key>
<string>2.0</string>
<key>IwsApiVersion</key>
Expand Down
29 changes: 29 additions & 0 deletions EPS HomeKit Bridge.indigoPlugin/Contents/Server Plugin/Actions.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,36 @@
<!-- Defaults to the main ColoradoFourWheeler forum on Indigo -->
<SupportURL>http://forums.indigodomo.com/viewforum.php?f=192</SupportURL>

<Action id="restartServer" deviceFilter="self" uiPath="DeviceActions">
<Name>Restart Accessory Server</Name>
<CallbackMethod>serverActionRestart</CallbackMethod>
</Action>

<Action id="restartServers">
<Name>Restart All Accessory Servers</Name>
<CallbackMethod>serverActionRestartAll</CallbackMethod>
</Action>

<Action id="sep_1" uiPath="DeviceActions"/>
<Action id="sep_2"/>

<Action id="refreshHomeKitDevice" deviceFilter="self" uiPath="DeviceActions">
<Name>Force HomeKit Refresh</Name>
<CallbackMethod>serverActionRefreshDevice</CallbackMethod>
<ConfigUI>
<Field type="menu" id="deviceList" >
<Label> </Label>
<List class="self" filter="" method="serverListJSONDevicesForAction" dynamicReload="true" />
</Field>
</ConfigUI>
</Action>

<Action id="restartServersAll" deviceFilter="self">
<Name>Force HomeKit Refresh On All Items</Name>
<CallbackMethod>serverActionRefreshDeviceAll</CallbackMethod>
</Action>

<Action id="sep_3" uiPath="DeviceActions"/>

<!-- Hidden Actions For API -->
<Action id="voiceAPI" uiPath="hidden">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,5 +60,12 @@
<Field type="textfield" id="apiport" defaultValue="8558" hidden="false">
<Label>Enhanced API port:</Label>
</Field>

<Field id="sep_apiport" type="separator" />

<Field type="checkbox" id="newpackage" defaultValue="true" >
<Label>New Methods:</Label>
<Description>Use new library methods for this release</Description>
</Field>

</PluginConfig>
Original file line number Diff line number Diff line change
Expand Up @@ -1016,9 +1016,14 @@ def detCharacteristicValues (self, classes, sourceDict, isOptional = False):
# Create the characteristic as an attribute
classname = "characteristic_{}".format(characteristic)
if classname in classes:
self.logger.threaddebug (u"Adding {} attribute to {}".format(characteristic, self.alias.value))
cclass = classes[classname]
setattr (self, characteristic, cclass())
if not characteristic in dir(self):
self.logger.threaddebug (u"Adding {} attribute to {}".format(characteristic, self.alias.value))
cclass = classes[classname]
setattr (self, characteristic, cclass())

else:
# Using the cache, remove the characteristic so it will repopulate on refreshes
if characteristic in self.characterDict: del(self.characterDict[characteristic])

if getter == "attr_STUB":
# Add the default value to the characterdict so it passes through to the API and then exit out
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,13 @@ def __init__(self, plugin):
"""

try:
if plugin is None: return # pre-loading before init

self.PluginBase = plugin # References the Indigo plugin
self._set_log_format() # Set the standard log format
self._init_libraries() # Initialize the factory libs

self.logger.info ("{} {} loaded".format(__modname__, __version__))
self.logger.debug ("{} {} loaded".format(__modname__, __version__))

except Exception as e:
self.logger.error (ex.stack_trace(e))
Expand Down
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,52 @@
kExceptionOutputPrefix = "\n\n\t\t\t\t\t\t\t "

class CalcsException(Exception):
# Generic error
pass

class TypeConversionError(Exception):
# Error converting from one data type to another
pass

###
def convert_temperature (value, toCelsius = False, asInteger = False):
"""
Convert a temperature value to Celsius or Fahrenheit.
Arguments:
toCelsius: convert value to Celsius (default is Fahrenheit)
asInteger: returns full float value when false and integer value when true
Returns:
Converted value as a float
"""

try:
if toCelsius:
# Convert value to celsius
value = float(value)
value = (value - 32) / 1.8000
value = round(value, precision)

if asInteger: return int(value)

return value

else:
# Default: convert value to fahrenheit
value = float(value)
value = (value * 1.8000) + 32
value = round(value, precision)

if asInteger: return int(value)

return value

except Exception as e:
e.args += (value,)
e.args += (u"to Celsius: {}".format(toCelsius),)
raise CalcsException (kExceptionOutputPrefix + ex.stack_trace(e))


###
def filter_to_dict (filter):
Expand All @@ -54,7 +99,7 @@ def filter_to_dict (filter):
###
def type_to_unicode_output (obj):
"""
Converts the type of the object to a string representation.
Converts the type of the object to a string representation including the type (used for __str__ functions).
"""

try:
Expand All @@ -68,7 +113,7 @@ def type_to_unicode_output (obj):
###
def generic_unicode_output (tabtitle, tabcontent, obj, title = None):
"""
Generic unicode output for custom classes
Generic unicode output for custom classes (called by __str__ functions).
"""

try:
Expand Down Expand Up @@ -100,7 +145,7 @@ def generic_unicode_output (tabtitle, tabcontent, obj, title = None):
###
def generic_class_to_dict (obj):
"""
Using the same exclusions as generic_unicode_output, convert class data to a JSON record
Using the same exclusions as generic_unicode_output, convert class data to a dictionary object.
"""

try:
Expand Down Expand Up @@ -133,8 +178,112 @@ def generic_class_to_dict (obj):

return data



###
def convert_to_compared_datatype (source, destination):
"""
Converts the source value to the destination data type.
Arguments:
source: the source value who's data type needs to be changed
destination: the value that the data type will be derived from
Returns:
source: value of source converted to the data type of destination
"""

try:
converted = False # Assume failure

# Convert to string types for ease
stype = str(type(source)).replace("<type '", "").replace("'>", "")
dtype = str(type(destination)).replace("<type '", "").replace("'>", "")


# Convert from None
if stype == "NoneType":
if dtype == "float": source = 0.0
if dtype == "int": source = 0
if dtype == "bool": source = False
if dtype == "string": source = ""
converted = True

# Convert from Boolean
if stype == "bool":

# To integer
if dtype == "int":
if source: source = 1
if not source: source = 0
converted = True

# To float
elif dtype == "float":
if source: source = 1.0
if not source: source = 0.0
converted = True

# To string
elif dtype == "str":
if source: source = "true"
if not source: source = "false"
converted = True

# From string
if stype == "str":

# To unicode
if dtype == "unicode":
source = unicode(source)
converted = True

# To boolean
if dtype == "bool":
if source.lower() == "true":
source = True
else:
source = False # It's either absolutely true or it's always false

converted = True

# To integer
if dtype == "int":
try:
source = int(source)
converted = True
except:
raise TypeConversionError (u"{} value {} cannot be converted to {}".format(stype, source, dtype))

# To float
if dtype == "float":
try:
source = float(source)
converted = True
except:
raise TypeConversionError (u"{} value {} cannot be converted to {}".format(stype, source, dtype))

# From unicode to string
if stype == "unicode" and dtype == "str":
source = str(source)
converted = True

# From integer to float
if stype == "int" and dtype == "float":
source = float(source)
converted = True

# From float to integer
if stype == "float" and dtype == "int":
source = int(round(source))
converted = True

if not converted:
raise TypeConversionError (u"Unable to convert source {} to type {}".format(stype, dtype))

except Exception as e:
e.args += (u"{} to {}".format(stype, dtype),)
raise CalcsException (kExceptionOutputPrefix + ex.stack_trace(e))

return source



Expand Down
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ def homekit_type_and_firmware (self, keyword, devId, serverId):
self.logger.debug (u"Converting {} keyword for HomeKit type or firmware on '{}'".format(keyword, indigo.devices[devId].name))

if keyword is None or keyword == "":
return "N/A"
return "N/A"
elif keyword == "indigoModel":
return u"{}".format(indigo.devices[devId].model)
elif keyword == "indigoSubmodel":
Expand Down
Binary file not shown.
Loading

0 comments on commit f079678

Please sign in to comment.