Skip to content

Commit 3eadafb

Browse files
Add scene support
1 parent 7c85f3b commit 3eadafb

File tree

9 files changed

+115
-11
lines changed

9 files changed

+115
-11
lines changed

HA Menu.xcodeproj/project.pbxproj

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -373,9 +373,9 @@
373373
projectRoot = "";
374374
targets = (
375375
491F5298217CBF5200105921 /* HA Menu */,
376+
49BDE9E0237DA1580087F729 /* HA Menu Launcher */,
376377
491F52AA217CBF5400105921 /* HA MenuTests */,
377378
491F52B5217CBF5400105921 /* HA MenuUITests */,
378-
49BDE9E0237DA1580087F729 /* HA Menu Launcher */,
379379
);
380380
};
381381
/* End PBXProject section */
@@ -619,15 +619,15 @@
619619
CODE_SIGN_IDENTITY = "Apple Development";
620620
CODE_SIGN_STYLE = Automatic;
621621
COMBINE_HIDPI_IMAGES = YES;
622-
CURRENT_PROJECT_VERSION = 20;
622+
CURRENT_PROJECT_VERSION = 21;
623623
DEVELOPMENT_TEAM = VZ3Z8BPWPW;
624624
ENABLE_HARDENED_RUNTIME = YES;
625625
INFOPLIST_FILE = "HA Menu/Info.plist";
626626
LD_RUNPATH_SEARCH_PATHS = (
627627
"$(inherited)",
628628
"@executable_path/../Frameworks",
629629
);
630-
MARKETING_VERSION = 2.2.1;
630+
MARKETING_VERSION = 2.3.0;
631631
PRODUCT_BUNDLE_IDENTIFIER = "org.codechimp.HA-Menu";
632632
PRODUCT_NAME = "$(TARGET_NAME)";
633633
SWIFT_VERSION = 5.0;
@@ -642,15 +642,15 @@
642642
CODE_SIGN_IDENTITY = "Apple Development";
643643
CODE_SIGN_STYLE = Automatic;
644644
COMBINE_HIDPI_IMAGES = YES;
645-
CURRENT_PROJECT_VERSION = 20;
645+
CURRENT_PROJECT_VERSION = 21;
646646
DEVELOPMENT_TEAM = VZ3Z8BPWPW;
647647
ENABLE_HARDENED_RUNTIME = YES;
648648
INFOPLIST_FILE = "HA Menu/Info.plist";
649649
LD_RUNPATH_SEARCH_PATHS = (
650650
"$(inherited)",
651651
"@executable_path/../Frameworks",
652652
);
653-
MARKETING_VERSION = 2.2.1;
653+
MARKETING_VERSION = 2.3.0;
654654
PRODUCT_BUNDLE_IDENTIFIER = "org.codechimp.HA-Menu";
655655
PRODUCT_NAME = "$(TARGET_NAME)";
656656
SWIFT_VERSION = 5.0;
@@ -747,15 +747,15 @@
747747
CODE_SIGN_IDENTITY = "Apple Development";
748748
CODE_SIGN_STYLE = Automatic;
749749
COMBINE_HIDPI_IMAGES = YES;
750-
CURRENT_PROJECT_VERSION = 20;
750+
CURRENT_PROJECT_VERSION = 21;
751751
DEVELOPMENT_TEAM = VZ3Z8BPWPW;
752752
ENABLE_HARDENED_RUNTIME = YES;
753753
INFOPLIST_FILE = "HA Menu Launcher/Info.plist";
754754
LD_RUNPATH_SEARCH_PATHS = (
755755
"$(inherited)",
756756
"@executable_path/../Frameworks",
757757
);
758-
MARKETING_VERSION = 2.2.1;
758+
MARKETING_VERSION = 2.3.0;
759759
PRODUCT_BUNDLE_IDENTIFIER = "org.codechimp.HA-Menu-Launcher";
760760
PRODUCT_NAME = "$(TARGET_NAME)";
761761
SKIP_INSTALL = YES;
@@ -771,15 +771,15 @@
771771
CODE_SIGN_IDENTITY = "Apple Development";
772772
CODE_SIGN_STYLE = Automatic;
773773
COMBINE_HIDPI_IMAGES = YES;
774-
CURRENT_PROJECT_VERSION = 20;
774+
CURRENT_PROJECT_VERSION = 21;
775775
DEVELOPMENT_TEAM = VZ3Z8BPWPW;
776776
ENABLE_HARDENED_RUNTIME = YES;
777777
INFOPLIST_FILE = "HA Menu Launcher/Info.plist";
778778
LD_RUNPATH_SEARCH_PATHS = (
779779
"$(inherited)",
780780
"@executable_path/../Frameworks",
781781
);
782-
MARKETING_VERSION = 2.2.1;
782+
MARKETING_VERSION = 2.3.0;
783783
PRODUCT_BUNDLE_IDENTIFIER = "org.codechimp.HA-Menu-Launcher";
784784
PRODUCT_NAME = "$(TARGET_NAME)";
785785
SKIP_INSTALL = YES;

HA Menu/AppDelegate.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ extension AppDelegate {
5353
"domain_automations": true,
5454
"domain_inputbooleans": true,
5555
"domain_inputselects": true,
56+
"domain_scenes": true,
5657
"betaNotifications": false
5758
])
5859

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{
2+
"images" : [
3+
{
4+
"filename" : "[email protected]",
5+
"idiom" : "universal",
6+
"scale" : "1x"
7+
},
8+
{
9+
"filename" : "[email protected]",
10+
"idiom" : "universal",
11+
"scale" : "2x"
12+
},
13+
{
14+
"idiom" : "universal",
15+
"scale" : "3x"
16+
}
17+
],
18+
"info" : {
19+
"author" : "xcode",
20+
"version" : 1
21+
}
22+
}
1.31 KB
Loading
1.47 KB
Loading

HA Menu/MenuItemController.swift

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,8 @@ final class MenuItemController: NSObject, NSMenuDelegate {
194194
itemType = EntityTypes.inputSelectType
195195
case "automation":
196196
itemType = EntityTypes.automationType
197+
case "scene":
198+
itemType = EntityTypes.sceneType
197199
default:
198200
itemType = nil
199201
}
@@ -290,13 +292,23 @@ final class MenuItemController: NSObject, NSMenuDelegate {
290292
subMenu.addItem(optionMenuItem)
291293
}
292294
}
295+
293296
else {
294297
let menuItem = NSMenuItem()
295-
menuItem.action = #selector(self.toggleEntityState(_:))
298+
299+
if haEntity.domainType == EntityDomains.sceneDomain {
300+
menuItem.action = #selector(self.turnOnEntity(_:))
301+
menuItem.state = NSControl.StateValue.off
302+
menuItem.offStateImage = NSImage(named: "PlayButtonImage")
303+
}
304+
else {
305+
menuItem.action = #selector(self.toggleEntityState(_:))
306+
menuItem.state = ((haEntity.state == "on") ? NSControl.StateValue.on : NSControl.StateValue.off)
307+
}
308+
296309
menuItem.target = self
297310
menuItem.title = haEntity.friendlyName
298311
menuItem.keyEquivalent = ""
299-
menuItem.state = ((haEntity.state == "on") ? NSControl.StateValue.on : NSControl.StateValue.off)
300312
menuItem.representedObject = haEntity
301313
menuItem.tag = haEntity.type.rawValue // Tag defines what type of item it is
302314
// menuItem.image = NSImage(named: "StatusBarButtonImage")
@@ -374,6 +386,11 @@ final class MenuItemController: NSObject, NSMenuDelegate {
374386
haService.selectInputSelectOption(haEntity: haEntity, option: sender.title)
375387
}
376388

389+
@objc func turnOnEntity(_ sender: NSMenuItem) {
390+
let haEntity: HaEntity = sender.representedObject as! HaEntity
391+
haService.turnOnEntity(haEntity: haEntity)
392+
}
393+
377394
func checkForUpdate() {
378395
let parser = FeedParser(URL: releasesFeedURL)
379396

HA Menu/Models/HaEntity.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ enum EntityTypes: Int, CaseIterable {
1515
case automationType = 5
1616
case inputSelectType = 6
1717
case groupType = 7
18+
case sceneType = 8
1819
case unknownType = 999
1920
}
2021

@@ -24,6 +25,7 @@ enum EntityDomains: String, CaseIterable {
2425
case inputBooleanDomain = "input_boolean"
2526
case automationDomain = "automation"
2627
case inputSelectDomain = "input_select"
28+
case sceneDomain = "scene"
2729
case groupDomain = "group"
2830
case unknownDomain = "unknown"
2931
}
@@ -48,6 +50,8 @@ struct HaEntity {
4850
return EntityDomains.automationDomain
4951
case EntityDomains.inputSelectDomain.rawValue:
5052
return EntityDomains.inputSelectDomain
53+
case EntityDomains.sceneDomain.rawValue:
54+
return EntityDomains.sceneDomain
5155
case EntityDomains.groupDomain.rawValue:
5256
return EntityDomains.groupDomain
5357
default:
@@ -75,6 +79,8 @@ struct HaEntity {
7579
return EntityTypes.automationType
7680
case EntityDomains.inputSelectDomain:
7781
return EntityTypes.inputSelectType
82+
case EntityDomains.sceneDomain:
83+
return EntityTypes.sceneType
7884
case EntityDomains.groupDomain:
7985
return EntityTypes.groupType
8086
default:

HA Menu/Models/HaService.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,23 @@ class HaService {
150150

151151
task.resume()
152152
}
153+
154+
func turnOnEntity(haEntity: HaEntity) {
155+
let params = ["entity_id": haEntity.entityId]
156+
let urlString = "\(prefs.server)/api/services/\(haEntity.domain)/turn_on"
157+
158+
var request = createAuthURLRequest(url: URL(string: urlString)!)
159+
160+
request.httpMethod = "POST"
161+
request.httpBody = try? JSONSerialization.data(withJSONObject: params, options: [])
162+
163+
let session = URLSession.shared
164+
let task = session.dataTask(with: request, completionHandler: { data, response, error -> Void in
165+
print(String(data: data!, encoding: String.Encoding.utf8)!)
166+
})
167+
168+
task.resume()
169+
}
170+
153171

154172
}

HA Menu/Models/Preferences.swift

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ struct Preferences {
1616
}
1717
set {
1818
UserDefaults.standard.set(newValue, forKey: "settingsVersion")
19+
UserDefaults.standard.synchronize()
1920
}
2021
}
2122

@@ -30,6 +31,7 @@ struct Preferences {
3031
}
3132
set {
3233
UserDefaults.standard.set(newValue.trimmingCharacters(in: .whitespaces), forKey: "server")
34+
UserDefaults.standard.synchronize()
3335
}
3436
}
3537

@@ -39,6 +41,7 @@ struct Preferences {
3941
}
4042
set {
4143
UserDefaults.standard.set(newValue.trimmingCharacters(in: .whitespaces), forKey: "token")
44+
UserDefaults.standard.synchronize()
4245
}
4346
}
4447

@@ -48,6 +51,7 @@ struct Preferences {
4851
}
4952
set {
5053
UserDefaults.standard.set(newValue, forKey: "launch")
54+
UserDefaults.standard.synchronize()
5155
}
5256
}
5357

@@ -57,6 +61,7 @@ struct Preferences {
5761
}
5862
set {
5963
UserDefaults.standard.set(newValue, forKey: "betaNotifications")
64+
UserDefaults.standard.synchronize()
6065
}
6166
}
6267

@@ -85,6 +90,7 @@ struct Preferences {
8590
}
8691
set {
8792
UserDefaults.standard.set(newValue.trimmingCharacters(in: .whitespaces), forKey: "group")
93+
UserDefaults.standard.synchronize()
8894
}
8995
}
9096

@@ -105,6 +111,7 @@ struct Preferences {
105111
}
106112
set {
107113
UserDefaults.standard.set(newValue, forKey: "domain_lights")
114+
UserDefaults.standard.synchronize()
108115
}
109116
}
110117

@@ -114,6 +121,7 @@ struct Preferences {
114121
}
115122
set {
116123
UserDefaults.standard.set(newValue, forKey: "domain_switches")
124+
UserDefaults.standard.synchronize()
117125
}
118126
}
119127

@@ -147,6 +155,16 @@ struct Preferences {
147155
}
148156
}
149157

158+
var domainScenes: Bool {
159+
get {
160+
return UserDefaults.standard.bool(forKey: "domain_scenes")
161+
}
162+
set {
163+
UserDefaults.standard.set(newValue, forKey: "domain_scenes")
164+
UserDefaults.standard.synchronize()
165+
}
166+
}
167+
150168
var menuItems: [PrefMenuItem] {
151169
get {
152170
var decodedResponse = [PrefMenuItem]()
@@ -159,6 +177,12 @@ struct Preferences {
159177
do {
160178
let jsonData = jsonString.data(using: String.Encoding.utf8, allowLossyConversion: false)
161179
decodedResponse = try JSONDecoder().decode([PrefMenuItem].self, from: jsonData!)
180+
181+
// Upgrade with any new domains
182+
if !domainExists(domain: "scene", prefs: decodedResponse) {
183+
decodedResponse.append(PrefMenuItem(entityId: "scene", itemType: itemTypes.Domain, subMenu: false, enabled: domainScenes, friendlyName: "Scenes"))
184+
}
185+
162186
return decodedResponse
163187
}
164188
catch {
@@ -179,6 +203,9 @@ struct Preferences {
179203

180204
decodedResponse.append(PrefMenuItem(entityId: "input_select", itemType: itemTypes.Domain, subMenu: false, enabled: domainInputSelects, friendlyName: "Input Selects"))
181205

206+
decodedResponse.append(PrefMenuItem(entityId: "scene", itemType: itemTypes.Domain, subMenu: false, enabled: domainScenes, friendlyName: "Scenes"))
207+
208+
182209
// Init Groups from old setting
183210
for group in groups {
184211
decodedResponse.append(PrefMenuItem(entityId: group, itemType: itemTypes.Group, subMenu: false, enabled: true, friendlyName: ""))
@@ -203,6 +230,19 @@ struct Preferences {
203230
}
204231
}
205232

233+
private func domainExists(domain: String, prefs: [PrefMenuItem]) -> Bool {
234+
var foundDomain = false
235+
236+
for prefMenuItem in prefs {
237+
if prefMenuItem.entityId == domain {
238+
foundDomain = true
239+
break
240+
}
241+
}
242+
243+
return foundDomain
244+
}
245+
206246
func menuItemsWithFriendlyNames(groups: [HaEntity]) -> [String: PrefMenuItem] {
207247
var completedItems = [String: PrefMenuItem]()
208248

0 commit comments

Comments
 (0)