Skip to content

Commit

Permalink
Merge pull request #2 from LIFX/feature/add-capabilities
Browse files Browse the repository at this point in the history
Feature/add capabilities
  • Loading branch information
mitulmanish authored Apr 7, 2017
2 parents 41ea706 + a88258a commit b36786b
Show file tree
Hide file tree
Showing 7 changed files with 102 additions and 9 deletions.
12 changes: 12 additions & 0 deletions LIFXHTTPKit.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,11 @@
903A12CC1CE0640C0071D8F0 /* Group.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D94C6491B5671C300C0BCD2 /* Group.swift */; };
903A12CD1CE064100071D8F0 /* Location.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5D94C64B1B56726200C0BCD2 /* Location.swift */; };
903A12CE1CE064130071D8F0 /* Result.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DB41F4D1B2BD5E50006F2A5 /* Result.swift */; };
DD1E132F81EB962FED0C262F /* ProductInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */; };
DD1E13F233373003945C348D /* ProductInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */; };
DD1E1B4B1DF488D68F6F302D /* ProductInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */; };
DD1E1ED9D4663020C0323F96 /* ProductInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */; };
E9F4B5791E950F4800D0ED01 /* ProductInformation.swift in Sources */ = {isa = PBXBuildFile; fileRef = E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand Down Expand Up @@ -121,6 +126,7 @@
5DF649D81B2D436A0006EE03 /* LightTargetTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = LightTargetTests.swift; sourceTree = "<group>"; };
903A12B71CE050C70071D8F0 /* LIFXHTTPKit.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LIFXHTTPKit.h; sourceTree = "<group>"; };
908631CD1CDC7629006D9E47 /* LIFXHTTPKit.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = LIFXHTTPKit.framework; sourceTree = BUILT_PRODUCTS_DIR; };
E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ProductInformation.swift; sourceTree = "<group>"; };
/* End PBXFileReference section */

/* Begin PBXFrameworksBuildPhase section */
Expand Down Expand Up @@ -200,6 +206,7 @@
5DB41F4B1B2BD5DD0006F2A5 /* Light.swift */,
5D50E0581BC3A21800AED146 /* Scene.swift */,
5D50E05A1BC3A26A00AED146 /* State.swift */,
E9F4B5781E950F4800D0ED01 /* ProductInformation.swift */,
5D94C6491B5671C300C0BCD2 /* Group.swift */,
5D94C64B1B56726200C0BCD2 /* Location.swift */,
5DB41F4D1B2BD5E50006F2A5 /* Result.swift */,
Expand Down Expand Up @@ -463,6 +470,7 @@
5D05E61F1BB5296E007B917D /* ClientTests.swift in Sources */,
5D05E6201BB5296E007B917D /* LightTargetTests.swift in Sources */,
5D05E6211BB5296E007B917D /* SecretsHelper.swift in Sources */,
DD1E13F233373003945C348D /* ProductInformation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -485,6 +493,7 @@
5DB41F4E1B2BD5E50006F2A5 /* Result.swift in Sources */,
5D94C64C1B56726200C0BCD2 /* Location.swift in Sources */,
5DB41F461B2BD55C0006F2A5 /* LightTargetObserver.swift in Sources */,
DD1E1B4B1DF488D68F6F302D /* ProductInformation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -498,6 +507,7 @@
5D5898B51B1887530024D47B /* ClientTests.swift in Sources */,
5DF649D91B2D436A0006EE03 /* LightTargetTests.swift in Sources */,
5DA7AB341B369640008A8130 /* SecretsHelper.swift in Sources */,
DD1E1ED9D4663020C0323F96 /* ProductInformation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand All @@ -515,6 +525,7 @@
5D8BF5401BB5257D00A5575C /* Group.swift in Sources */,
5DF3F61A1BD45C0F0002E52D /* HTTPOperation.swift in Sources */,
5D8BF53B1BB5257200A5575C /* LightTarget.swift in Sources */,
E9F4B5791E950F4800D0ED01 /* ProductInformation.swift in Sources */,
5D8BF5421BB5258200A5575C /* Result.swift in Sources */,
5D8BF5371BB5256900A5575C /* Errors.swift in Sources */,
5D8BF53E1BB5257900A5575C /* Light.swift in Sources */,
Expand Down Expand Up @@ -542,6 +553,7 @@
903A12C81CE064010071D8F0 /* Color.swift in Sources */,
903A12CA1CE064070071D8F0 /* Scene.swift in Sources */,
903A12CB1CE064090071D8F0 /* State.swift in Sources */,
DD1E132F81EB962FED0C262F /* ProductInformation.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
7 changes: 6 additions & 1 deletion Source/HTTPSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -183,9 +183,14 @@ public class HTTPSession {
} else {
location = nil
}

var productInformation: ProductInformation?
if let productInformationJSONObject = lightJSONObject["product"] as? NSDictionary {
productInformation = ProductInformation(data: productInformationJSONObject)
}

let color = Color(hue: colorHue, saturation: colorSaturation, kelvin: colorKelvin)
let light = Light(id: id, power: power == "on", brightness: brightness, color: color, label: label, connected: connected, group: group, location: location, touchedAt: Date())
let light = Light(id: id, power: power == "on", brightness: brightness, color: color, productInformation: productInformation, label: label, connected: connected, group: group, location: location, touchedAt: Date())
lights.append(light)
} else {
return ([], HTTPKitError(code: .jsonInvalid, message: "JSON object is missing required properties"))
Expand Down
22 changes: 19 additions & 3 deletions Source/Light.swift
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,40 @@ public struct Light: Equatable, CustomStringConvertible {
public let power: Bool
public let brightness: Double
public let color: Color
public let productInformation: ProductInformation?
public let label: String
public let connected: Bool
public let group: Group?
public let location: Location?
public let touchedAt: Date?


public func toSelector() -> LightTargetSelector {
return LightTargetSelector(type: .ID, value: id)
}

func lightWithProperties(_ power: Bool? = nil, brightness: Double? = nil, color: Color? = nil, connected: Bool? = nil, touchedAt: Date? = nil) -> Light {
return Light(id: id, power: power ?? self.power, brightness: brightness ?? self.brightness, color: color ?? self.color, label: label, connected: connected ?? self.connected, group: group, location: location, touchedAt: touchedAt ?? Date())
func lightWithProperties(_ power: Bool? = nil, brightness: Double? = nil, color: Color? = nil, productInformation: ProductInformation? = nil, connected: Bool? = nil, touchedAt: Date? = nil) -> Light {
return Light(id: id, power: power ?? self.power, brightness: brightness ?? self.brightness, color: color ?? self.color, productInformation: productInformation ?? self.productInformation, label: label, connected: connected ?? self.connected, group: group, location: location, touchedAt: touchedAt ?? Date())
}

// MARK: Capabilities

public var hasColor: Bool {
return self.productInformation?.capabilities?.hasColor ?? false
}

public var hasIR: Bool {
return self.productInformation?.capabilities?.hasIR ?? false
}

public var hasMultiZone: Bool {
return self.productInformation?.capabilities?.hasMulitiZone ?? false
}

// MARK: Printable

public var description: String {
return "<Light id: \"\(id)\", label: \"\(label)\", power: \(power), brightness: \(brightness), color: \(color), connected: \(connected), group: \(group), location: \(location), touchedAt: \(touchedAt)>"
return "<Light id: \"\(id)\", label: \"\(label)\", power: \(power), brightness: \(brightness), color: \(color), connected: \(connected), group: \(String(describing: group)), location: \(String(describing: location)), touchedAt: \(String(describing: touchedAt))>"
}
}

Expand Down
18 changes: 15 additions & 3 deletions Source/LightTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -343,12 +343,12 @@ public class LightTarget {
var kelvinTotal: Int = 0
for light in lights {
let color = light.color
hueXTotal += sin(color.hue * 2.0 * M_PI / Color.maxHue)
hueYTotal += cos(color.hue * 2.0 * M_PI / Color.maxHue)
hueXTotal += sin(color.hue * 2.0 * .pi / Color.maxHue)
hueYTotal += cos(color.hue * 2.0 * .pi / Color.maxHue)
saturationTotal += color.saturation
kelvinTotal += color.kelvin
}
var hue: Double = atan2(hueXTotal, hueYTotal) / (2.0 * M_PI);
var hue: Double = atan2(hueXTotal, hueYTotal) / (2.0 * .pi);
if hue < 0.0 {
hue += 1.0
}
Expand Down Expand Up @@ -402,4 +402,16 @@ public class LightTarget {
private func deriveCount() -> Int {
return lights.count
}

public var supportsColor: Bool {
return lights.map { $0.hasColor }.contains(true)
}

public var supportsIR: Bool {
return lights.map { $0.hasIR }.contains(true)
}

public var supportsMultiZone: Bool {
return lights.map { $0.hasMultiZone }.contains(true)
}
}
48 changes: 48 additions & 0 deletions Source/ProductInformation.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
//
// ProductInformation.swift
// LIFXHTTPKit
//
// Created by LIFX Laptop on 5/4/17.

import Foundation

public struct ProductInformation {
public let productName: String
public let manufacturer: String
public let capabilities: Capabilities?

public init?(data: NSDictionary) {
guard let name = data["name"] as? String, let company = data["company"] as? String, let productCapabilities = data["capabilities"] as? NSDictionary else {
return nil
}
productName = name
manufacturer = company
capabilities = Capabilities(data: productCapabilities)
}

var description: String {
return "Name: \(productName) - manufactured by \(manufacturer) Capabilities supported - \(String(describing: capabilities?.description))"
}
}

public struct Capabilities {
public let hasColor: Bool
public let hasIR: Bool
public let hasMulitiZone: Bool

public init?(data: NSDictionary) {
guard let hasColor = data["has_color"] as? Bool,
let hasIR = data["has_ir"] as? Bool, let multiZone = data["has_multizone"] as? Bool else {
return nil
}

self.hasColor = hasColor
self.hasIR = hasIR
self.hasMulitiZone = multiZone
}

var description: String {
return "Color - \(hasColor), Infra-red \(hasIR), Multiple zones - \(hasMulitiZone)"
}

}
2 changes: 1 addition & 1 deletion Tests/ClientHelper.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ class ClientHelper {
}
semaphore.signal()
}
semaphore.wait(timeout: DispatchTime.distantFuture)
_ = semaphore.wait(timeout: DispatchTime.distantFuture)
return client
}()
}
2 changes: 1 addition & 1 deletion Tests/LightTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,6 @@ class LightTests: XCTestCase {
}

private func newLight() -> Light {
return Light(id: "d3b2f2d97452", power: true, brightness: 0.5, color: Color.white(Color.defaultKelvin), label: "Lamp", connected: true, group: nil, location: nil, touchedAt: nil)
return Light(id: "d3b2f2d97452", power: true, brightness: 0.5, color: Color.white(Color.defaultKelvin), productInformation: nil, label: "Lamp", connected: true, group: nil, location: nil, touchedAt: nil)
}
}

0 comments on commit b36786b

Please sign in to comment.