From 2a1bc752fe37a269dd2713b2073df3614ab40dd5 Mon Sep 17 00:00:00 2001 From: TheMisfit68 Date: Sun, 17 Dec 2023 09:25:47 +0100 Subject: [PATCH 1/2] Adde StatelessProgrammable switch accessory and prepared to fire its events --- .../FunctionKey.swift | 121 ++++++++++++++++++ .../StatelessProgrammableSwitch.swift | 21 +++ HAPiNest.xcodeproj/project.pbxproj | 34 +++-- HAPiNest/FunctionKey.swift | 120 ----------------- HAPiNest/SceneNames.xcstrings | 76 ----------- MainConfiguration.swift | 12 +- PLCConfiguration.swift | 24 +--- 7 files changed, 170 insertions(+), 238 deletions(-) create mode 100644 Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift create mode 100644 HAP Extensions/Custom Accessories/StatelessProgrammableSwitch.swift delete mode 100644 HAPiNest/FunctionKey.swift delete mode 100644 HAPiNest/SceneNames.xcstrings diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift new file mode 100644 index 00000000..d98be184 --- /dev/null +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift @@ -0,0 +1,121 @@ +// +// FunctionKey.swift +// HAPiNest +// +// Created by Jan Verrept on 31/12/2020. +// Copyright © 2020 Jan Verrept. All rights reserved. +// + +import Foundation + +import Cocoa +import HAP +import SoftPLC +import ModbusDriver +import IOTypes +import JVCocoa + + +/// A PLC-Class type object that is not an Accessory-Delegate +/// because it has no Accessory associated with it, +/// it only processes hardware-signals +class FunctionKey:PLCClassAccessoryDelegate{ + + var characteristicChanged: Bool = false + var hardwareFeedbackChanged: Bool = false + + + private var inputPuls:Bool = false + private var inputTriggered:EBool + + var clicked:Bool = false{ + didSet{ + if clicked{ +#warning("DEBUGPRINT") // TODO: - remove temp print statement + print("🐞\tClicked") + } + clicked.reset() + } + } + + let doubleclikInterval:TimeInterval + let doubleClickTimer:DigitalTimer + var doubleClicked:Bool = false{ + didSet{ + if doubleClicked{ +#warning("DEBUGPRINT") // TODO: - remove temp print statement + print("🐞\tDoubleClicked") + } + doubleClicked.reset() + } + } + + let longPressTime:TimeInterval + let longPressTimer:DigitalTimer + var longPressed:Bool = false{ + didSet{ + if longPressed{ +#warning("DEBUGPRINT") // TODO: - remove temp print statement + print("🐞\tPressedlong") + } + longPressed.reset() + } + } + + + override init(){ + + self.inputTriggered = EBool(&inputPuls) + + self.doubleclikInterval = 1.0 + self.doubleClickTimer = DigitalTimer.OffDelay(time: doubleclikInterval) + + self.longPressTime = 2.0 + self.longPressTimer = DigitalTimer.OnDelay(time: longPressTime) + + super.init() + } + + var inputSignal:DigitalInputSignal{ + let ioSymbol:SoftPLC.IOSymbol = .functionKey(circuit:String(localized: "\(instanceName)", table:"AccessoryNames")) + return plc.signal(ioSymbol:ioSymbol) as! DigitalInputSignal + } + + public func assignInputParameters(){ + + if let hardwarePuls = inputSignal.logicalValue{ + inputPuls = hardwarePuls + }else{ + inputPuls = false + } + + } + + public func assignOutputParameters(){ + // Function keys have no outputs associated with them! + } + + // MARK: - PLC Processing + public func runCycle() { + + let risingEdge = inputTriggered.🔼 + + if risingEdge && !doubleClickTimer.output{ + clicked.set() + }else if risingEdge && doubleClickTimer.output{ + doubleClicked.set() + }else if longPressTimer.output{ + longPressed.set() + } + +// reevaluate(&clicked, characteristic:accessory.programmableSwitchEvent, hardwareFeedback: hardwarePowerState) +// reevaluate(&doubleClicked, characteristic:accessory.outlet.powerState, hardwareFeedback: hardwarePowerState) + + + + doubleClickTimer.input = inputPuls + longPressTimer.input = inputPuls + + } + +} diff --git a/HAP Extensions/Custom Accessories/StatelessProgrammableSwitch.swift b/HAP Extensions/Custom Accessories/StatelessProgrammableSwitch.swift new file mode 100644 index 00000000..e64469a2 --- /dev/null +++ b/HAP Extensions/Custom Accessories/StatelessProgrammableSwitch.swift @@ -0,0 +1,21 @@ +// +// StatelessProgrammableSwitch.swift +// HAPiNest +// +// Created by Jan Verrept on 17/12/2023. +// Copyright © 2023 Jan Verrept. All rights reserved. +// +import Foundation +import HAP + +#warning("TODO") // TODO: - Create a pull request to get this implemented by HAP itself +extension HAP.Accessory { + open class ProgrammableSwitch: Accessory { + public let primaryService:Service.StatelessProgrammableSwitch = Service.StatelessProgrammableSwitch() + + public init(info: Service.Info, additionalServices: [Service] = []) { + super.init(info: info, type: .programmableSwitch, services: [primaryService] + additionalServices) + } + } +} + diff --git a/HAPiNest.xcodeproj/project.pbxproj b/HAPiNest.xcodeproj/project.pbxproj index 735eb347..29300562 100644 --- a/HAPiNest.xcodeproj/project.pbxproj +++ b/HAPiNest.xcodeproj/project.pbxproj @@ -11,7 +11,6 @@ DC0761B02A8A9DA3009FA191 /* DashboardPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0761AF2A8A9DA3009FA191 /* DashboardPreview.swift */; }; DC0761B12A8A9DA3009FA191 /* HomeKitServerPreview.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC0761AE2A8A9DA3009FA191 /* HomeKitServerPreview.swift */; }; DC0CA92C268BBD0700E5AB06 /* MilightDriver in Frameworks */ = {isa = PBXBuildFile; productRef = DC0CA92B268BBD0700E5AB06 /* MilightDriver */; }; - DC120EE72AE31AF10052F1A6 /* ServiceNames.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DC120EE62AE31AF10052F1A6 /* ServiceNames.xcstrings */; }; DC1888352961C0CF00D3363D /* EnableSwitchService.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC1888342961C0CF00D3363D /* EnableSwitchService.swift */; }; DC2C19BF26BB3BD400A3AB83 /* HAP in Frameworks */ = {isa = PBXBuildFile; productRef = DC2C19BE26BB3BD400A3AB83 /* HAP */; }; DC342E0C2AEE74EF00C578A2 /* PLCAccessoryDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC342E0B2AEE74EF00C578A2 /* PLCAccessoryDelegate.swift */; }; @@ -33,10 +32,9 @@ DC54B6F72570628E00D9169F /* HomeKitServerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC3626EF256D9B0800F0AC35 /* HomeKitServerView.swift */; }; DC54B6FD2570686D00D9169F /* PLCConfiguration.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC23DF9424E7499A00DD8371 /* PLCConfiguration.swift */; }; DC55156A296AE2A9003432CD /* ElectricCarAccessory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC551569296AE2A9003432CD /* ElectricCarAccessory.swift */; }; + DC6DEE212B2E5EE300BDAB31 /* FunctionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC6DEE202B2E5EE300BDAB31 /* FunctionKey.swift */; }; DC746D7325ACA97A00B33314 /* SmartSprinklerAccessory.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC746D7225ACA97A00B33314 /* SmartSprinklerAccessory.swift */; }; DC846E3A26D996E9002CEDFB /* JVCocoa in Frameworks */ = {isa = PBXBuildFile; productRef = DC846E3926D996E9002CEDFB /* JVCocoa */; }; - DC87DC852AF31227003ABD83 /* SceneNames.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DC87DC842AF31227003ABD83 /* SceneNames.xcstrings */; }; - DC8D0F69259DAA6A00DD04E4 /* FunctionKey.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC8D0F68259DAA6A00DD04E4 /* FunctionKey.swift */; }; DC90DA642732817000068839 /* TizenSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC90DA5E2732817000068839 /* TizenSettingsView.swift */; }; DC90DA652732817000068839 /* PreferencesView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC90DA5F2732817000068839 /* PreferencesView.swift */; }; DC90DA672732817000068839 /* GeneralSettingsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC90DA612732817000068839 /* GeneralSettingsView.swift */; }; @@ -45,8 +43,9 @@ DC90DA6C2732828200068839 /* DashboardView.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC90DA6B2732828200068839 /* DashboardView.swift */; }; DC9963892AD3073000915EAC /* CirtcuitEnabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9963882AD3073000915EAC /* CirtcuitEnabler.swift */; }; DCA37CF926BB29EF003CC3BF /* HAPTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA37CF826BB29EF003CC3BF /* HAPTests.swift */; }; - DCA3DF312B28D97000554A8A /* DimmerTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA3DF302B28D97000554A8A /* DimmerTimer.swift */; }; + DCA3DF312B28D97000554A8A /* BrightnessTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA3DF302B28D97000554A8A /* BrightnessTimer.swift */; }; DCAB996A2A816734005FCC29 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = DCAB99692A816734005FCC29 /* README.md */; }; + DCBBC7082B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBBC7072B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift */; }; DCBCFB5529678657000F0376 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBCFB5429678657000F0376 /* Enums.swift */; }; DCC01B5825B434BC00984BB5 /* SmartSprinkler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC01B5725B434BC00984BB5 /* SmartSprinkler.swift */; }; DCC1D8C529886687000067D0 /* LeafAccessoryDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCC1D8C429886687000067D0 /* LeafAccessoryDelegate.swift */; }; @@ -77,7 +76,6 @@ /* Begin PBXFileReference section */ DC0761AE2A8A9DA3009FA191 /* HomeKitServerPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HomeKitServerPreview.swift; sourceTree = ""; }; DC0761AF2A8A9DA3009FA191 /* DashboardPreview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DashboardPreview.swift; sourceTree = ""; }; - DC120EE62AE31AF10052F1A6 /* ServiceNames.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = ServiceNames.xcstrings; sourceTree = ""; }; DC1888342961C0CF00D3363D /* EnableSwitchService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnableSwitchService.swift; sourceTree = ""; }; DC197CAA24D9A74300C07E90 /* MilightAccessoryDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = MilightAccessoryDelegate.swift; sourceTree = ""; }; DC23DF8C24E73F8600DD8371 /* DimmableLight.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DimmableLight.swift; sourceTree = ""; }; @@ -99,11 +97,10 @@ DC54B6C72570586E00D9169F /* HAPiNest.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = HAPiNest.entitlements; sourceTree = ""; }; DC551569296AE2A9003432CD /* ElectricCarAccessory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ElectricCarAccessory.swift; sourceTree = ""; }; DC5A4C2324D9A952001CF95B /* TizenAccessoryDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TizenAccessoryDelegate.swift; sourceTree = ""; }; + DC6DEE202B2E5EE300BDAB31 /* FunctionKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FunctionKey.swift; sourceTree = ""; }; DC6E461523B75BF8006A3E61 /* ToDo.md */ = {isa = PBXFileReference; lastKnownFileType = net.daringfireball.markdown; path = ToDo.md; sourceTree = ""; }; DC746D7225ACA97A00B33314 /* SmartSprinklerAccessory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartSprinklerAccessory.swift; sourceTree = ""; }; DC7FB14026C99142003CAFB0 /* JVCocoa */ = {isa = PBXFileReference; lastKnownFileType = folder; name = JVCocoa; path = ../../JVCocoa; sourceTree = ""; }; - DC87DC842AF31227003ABD83 /* SceneNames.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = SceneNames.xcstrings; sourceTree = ""; }; - DC8D0F68259DAA6A00DD04E4 /* FunctionKey.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FunctionKey.swift; sourceTree = ""; }; DC90DA5E2732817000068839 /* TizenSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TizenSettingsView.swift; sourceTree = ""; }; DC90DA5F2732817000068839 /* PreferencesView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = PreferencesView.swift; sourceTree = ""; }; DC90DA612732817000068839 /* GeneralSettingsView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = GeneralSettingsView.swift; sourceTree = ""; }; @@ -117,8 +114,9 @@ DC9EFF2224F3131F001B70EE /* DoorLock.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DoorLock.swift; sourceTree = ""; }; DCA37CF626BB29EF003CC3BF /* HAPiNestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HAPiNestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DCA37CF826BB29EF003CC3BF /* HAPTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HAPTests.swift; sourceTree = ""; }; - DCA3DF302B28D97000554A8A /* DimmerTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DimmerTimer.swift; sourceTree = ""; }; + DCA3DF302B28D97000554A8A /* BrightnessTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrightnessTimer.swift; sourceTree = ""; }; DCAB99692A816734005FCC29 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; + DCBBC7072B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatelessProgrammableSwitch.swift; sourceTree = ""; }; DCBCFB5429678657000F0376 /* Enums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = ""; }; DCC01B5725B434BC00984BB5 /* SmartSprinkler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartSprinkler.swift; sourceTree = ""; }; DCC1D8C429886687000067D0 /* LeafAccessoryDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LeafAccessoryDelegate.swift; sourceTree = ""; }; @@ -199,19 +197,16 @@ children = ( DCD592F8270A6C2600882387 /* HAPiNestApp.swift */, DC342E0D2AEE757E00C578A2 /* CyclicPoller.swift */, - DC8D0F68259DAA6A00DD04E4 /* FunctionKey.swift */, DC54B6C62570586E00D9169F /* Info.plist */, DC54B6C72570586E00D9169F /* HAPiNest.entitlements */, DC54B6C12570586E00D9169F /* Assets.xcassets */, DC4D66792A956AC1004C9D30 /* Localizable.xcstrings */, - DC87DC842AF31227003ABD83 /* SceneNames.xcstrings */, DC4D667B2A9571BA004C9D30 /* AccessoryNames.xcstrings */, - DC120EE62AE31AF10052F1A6 /* ServiceNames.xcstrings */, DCF7D5AB2AD0D106000010AA /* TVChannelNames.xcstrings */, DC90DA6A2732828200068839 /* MainWindow */, DC90DA5D2732817000068839 /* PreferencesWindow */, DC2D4572256E486D00DF3EC5 /* HomekitServer */, - DCA3DF322B28D99000554A8A /* AdaptableLightning */, + DCA3DF322B28D99000554A8A /* AmbientLightning */, ); path = HAPiNest; sourceTree = ""; @@ -258,6 +253,7 @@ DC2D4573256E48C100DF3EC5 /* PLCClassAccessoryDelegates */ = { isa = PBXGroup; children = ( + DC6DEE202B2E5EE300BDAB31 /* FunctionKey.swift */, DC23DF8C24E73F8600DD8371 /* DimmableLight.swift */, DC9963882AD3073000915EAC /* CirtcuitEnabler.swift */, DC23DF8E24E73FB900DD8371 /* Light.swift */, @@ -307,17 +303,18 @@ path = HAPiNestTests; sourceTree = ""; }; - DCA3DF322B28D99000554A8A /* AdaptableLightning */ = { + DCA3DF322B28D99000554A8A /* AmbientLightning */ = { isa = PBXGroup; children = ( - DCA3DF302B28D97000554A8A /* DimmerTimer.swift */, + DCA3DF302B28D97000554A8A /* BrightnessTimer.swift */, ); - path = AdaptableLightning; + path = AmbientLightning; sourceTree = ""; }; DCA8FA1B25B2FE0900532E4A /* Custom Accessories */ = { isa = PBXGroup; children = ( + DCBBC7072B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift */, DCD1230F25ACE01C00060708 /* StatelessGarageDoorOpenerAccessory.swift */, DC746D7225ACA97A00B33314 /* SmartSprinklerAccessory.swift */, DC551569296AE2A9003432CD /* ElectricCarAccessory.swift */, @@ -468,11 +465,9 @@ buildActionMask = 2147483647; files = ( DCF7D5AC2AD0D106000010AA /* TVChannelNames.xcstrings in Resources */, - DC87DC852AF31227003ABD83 /* SceneNames.xcstrings in Resources */, DCAB996A2A816734005FCC29 /* README.md in Resources */, DC54B6C22570586E00D9169F /* Assets.xcassets in Resources */, DC4D667A2A956AC1004C9D30 /* Localizable.xcstrings in Resources */, - DC120EE72AE31AF10052F1A6 /* ServiceNames.xcstrings in Resources */, DC4D667C2A9571BA004C9D30 /* AccessoryNames.xcstrings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; @@ -508,16 +503,17 @@ DC746D7325ACA97A00B33314 /* SmartSprinklerAccessory.swift in Sources */, DC0761B12A8A9DA3009FA191 /* HomeKitServerPreview.swift in Sources */, DC55156A296AE2A9003432CD /* ElectricCarAccessory.swift in Sources */, - DC8D0F69259DAA6A00DD04E4 /* FunctionKey.swift in Sources */, DC342E0E2AEE757E00C578A2 /* CyclicPoller.swift in Sources */, DCCF8CCC296B4BB400B1C50F /* Accessory.swift in Sources */, DCC9603D2670305000FB84BC /* Hapinest.docc in Sources */, DCCBE29C25B8B7D800BAED50 /* ToggleableOutlet.swift in Sources */, + DC6DEE212B2E5EE300BDAB31 /* FunctionKey.swift in Sources */, + DCBBC7082B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift in Sources */, DC0761B02A8A9DA3009FA191 /* DashboardPreview.swift in Sources */, DC90DA642732817000068839 /* TizenSettingsView.swift in Sources */, DC54B6F42570628B00D9169F /* HomeKitServer.swift in Sources */, DC4D6DE225713CD00087E51D /* DimmableLight.swift in Sources */, - DCA3DF312B28D97000554A8A /* DimmerTimer.swift in Sources */, + DCA3DF312B28D97000554A8A /* BrightnessTimer.swift in Sources */, DCD592F9270A6C2600882387 /* HAPiNestApp.swift in Sources */, DC90DA652732817000068839 /* PreferencesView.swift in Sources */, DC90DA692732817000068839 /* WeatherKitSettingsView.swift in Sources */, diff --git a/HAPiNest/FunctionKey.swift b/HAPiNest/FunctionKey.swift deleted file mode 100644 index 81c602f2..00000000 --- a/HAPiNest/FunctionKey.swift +++ /dev/null @@ -1,120 +0,0 @@ -// -// FunctionKey.swift -// HAPiNest -// -// Created by Jan Verrept on 31/12/2020. -// Copyright © 2020 Jan Verrept. All rights reserved. -// - -import Foundation - -import Cocoa -import HAP -import SoftPLC -import ModbusDriver -import IOTypes -import JVCocoa - - -/// A PLC-Class type object that is not an Accessory-Delegate -/// because it has no Accessory associated with it, -/// it only processes hardware-signals -class FunctionKey:PLCClass, Parameterizable, CyclicRunnable{ - - let shorcutDriver:ShortcutsDriver - - private var inputPuls:Bool = false - private var inputTriggered:EBool - - var clicked:Bool = false{ - didSet{ - if clicked{ - try? shorcutDriver.run("HomekitScene",withParameter: clickedScene) - } - clicked.reset() - } - } - let clickedScene:String - - let doubleclikInterval:TimeInterval - let doubleClickTimer:DigitalTimer - var doubleClicked:Bool = false{ - didSet{ - if doubleClicked, let sceneToRun = doubleClickedScene{ - try? shorcutDriver.run("HomekitScene",withParameter: sceneToRun) - } - doubleClicked.reset() - } - } - let doubleClickedScene:String? - - let longPressTime:TimeInterval - let longPressTimer:DigitalTimer - var longPressed:Bool = false{ - didSet{ - if longPressed, let sceneToRun = longPressScene{ - try? shorcutDriver.run("HomekitScene",withParameter: sceneToRun) - } - longPressed.reset() - } - } - let longPressScene:String? - - - init(clicked:String, doubleClicked:String?, longPress:String?){ - - self.shorcutDriver = ShortcutsDriver() - - self.inputTriggered = EBool(&inputPuls) - - self.clickedScene = clicked - - self.doubleclikInterval = 1.0 - self.doubleClickTimer = DigitalTimer.OffDelay(time: doubleclikInterval) - self.doubleClickedScene = doubleClicked - - self.longPressTime = 2.0 - self.longPressTimer = DigitalTimer.OnDelay(time: longPressTime) - self.longPressScene = longPress - - super.init() - } - - var inputSignal:DigitalInputSignal{ - let ioSymbol:SoftPLC.IOSymbol = .functionKey(circuit:String(localized: "\(instanceName)", table:"AccessoryNames")) - return plc.signal(ioSymbol:ioSymbol) as! DigitalInputSignal - } - - public func assignInputParameters(){ - - if let hardwarePuls = inputSignal.logicalValue{ - inputPuls = hardwarePuls - }else{ - inputPuls = false - } - - } - - public func assignOutputParameters(){ - // Function keys have no outputs associated with them! - } - - // MARK: - PLC Processing - public func runCycle() { - - let risingEdge = inputTriggered.🔼 - - if risingEdge && !doubleClickTimer.output{ - clicked.set() - }else if risingEdge && doubleClickTimer.output{ - doubleClicked.set() - }else if longPressTimer.output{ - longPressed.set() - } - - doubleClickTimer.input = inputPuls - longPressTimer.input = inputPuls - - } - -} diff --git a/HAPiNest/SceneNames.xcstrings b/HAPiNest/SceneNames.xcstrings deleted file mode 100644 index d98e9e8d..00000000 --- a/HAPiNest/SceneNames.xcstrings +++ /dev/null @@ -1,76 +0,0 @@ -{ - "sourceLanguage" : "en", - "strings" : { - "Scene 01" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Alles uit" - } - } - } - }, - "Scene 01L" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Anti-diefstal" - } - } - } - }, - "Scene 02" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gaan slapen #1" - } - } - } - }, - "Scene 02L" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Beneden aan" - } - } - } - }, - "Scene 03" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Gaan slapen #2" - } - } - } - }, - "Scene 03L" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Beneden aan" - } - } - } - }, - "Scene 04" : { - "localizations" : { - "nl" : { - "stringUnit" : { - "state" : "translated", - "value" : "Scene 04" - } - } - } - } - }, - "version" : "1.0" -} \ No newline at end of file diff --git a/MainConfiguration.swift b/MainConfiguration.swift index 41701870..07ddd799 100644 --- a/MainConfiguration.swift +++ b/MainConfiguration.swift @@ -39,7 +39,13 @@ struct MainConfiguration{ static let Accessories:[Accessory : any AccessoryDelegate] = [ - + // Function Keys + Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Frontdoor", table:"AccessoryNames"), serialNumber: "40000")) : PLCAccessoryDelegate(), + Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Left side bed", table:"AccessoryNames"), serialNumber: "40001")) : PLCAccessoryDelegate(), + Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Right side bed", table:"AccessoryNames"), serialNumber: "40002")) : PLCAccessoryDelegate(), + Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Landing", table:"AccessoryNames"), serialNumber: "40003")) : PLCAccessoryDelegate(), + + // MARK: - Dimmable Lights Accessory.Lightbulb(info: Service.Info(name:String(localized:"Bathroom Mood Lights", table:"AccessoryNames"), serialNumber: "00002", manufacturer: "MOXA"), isDimmable: true) : PLCAccessoryDelegate(), @@ -148,8 +154,8 @@ struct MainConfiguration{ ]) : TizenAccessoryDelegate(tvName:String(localized:"TV Upstairs", table:"AccessoryNames"), macAddress: "7C:64:56:80:4E:90", ipAddress: "192.168.0.116", port: 8002, deviceName: "HAPiNestServer"), // MARK: - Other - Accessory.ElectricCar(info: Service.Info(name: String(localized:"Electric Car", table:"AccessoryNames"), serialNumber: "30003", manufacturer: "Nissan")) : LeafAccessoryDelegate(leafProtocol: LeafProtocolV2()) - +// Accessory.ElectricCar(info: Service.Info(name: String(localized:"Electric Car", table:"AccessoryNames"), serialNumber: "30003", manufacturer: "Nissan")) : LeafAccessoryDelegate(leafProtocol: LeafProtocolV2()) +// // (Accessory.init(info: Service.Info(name:String(localized:"Zonnepanelen", table:"AccessoryNames"), serialNumber: "30001", manufacturer: "SMA"), diff --git a/PLCConfiguration.swift b/PLCConfiguration.swift index 397f08aa..a49fee13 100644 --- a/PLCConfiguration.swift +++ b/PLCConfiguration.swift @@ -170,26 +170,10 @@ extension MainConfiguration{ String(localized:"Landing Light Enable", table:"AccessoryNames") : CirtcuitEnabler(), // Function keys - String(localized:"Function Key Frontdoor", table:"AccessoryNames") : FunctionKey( - clicked:String(localized: "Scene 01", table: "SceneNames"), - doubleClicked: nil, - longPress: String(localized: "Scene 01L", table: "SceneNames") - ), - String(localized:"Function Key Left side bed", table:"AccessoryNames") : FunctionKey( - clicked:String(localized: "Scene 02", table: "SceneNames"), - doubleClicked: nil, - longPress:String(localized: "Scene 02L", table: "SceneNames") - ), - String(localized:"Function Key Right side bed", table:"AccessoryNames") : FunctionKey( - clicked:String(localized: "Scene 03", table: "SceneNames"), - doubleClicked: nil, - longPress: String(localized: "Scene 03L", table: "SceneNames") - ), - String(localized:"Function Key Landing", table:"AccessoryNames") : FunctionKey( - clicked:String(localized: "Scene 04", table: "SceneNames"), - doubleClicked: nil, - longPress: nil - ), + String(localized:"Function Key Frontdoor", table:"AccessoryNames") : FunctionKey(), + String(localized:"Function Key Left side bed", table:"AccessoryNames") : FunctionKey(), + String(localized:"Function Key Right side bed", table:"AccessoryNames") : FunctionKey(), + String(localized:"Function Key Landing", table:"AccessoryNames") : FunctionKey(), // Dimmable lights String(localized:"Bathroom Mood Lights", table:"AccessoryNames") : DimmableLight(), From cefe47a190684d14f151013fa7876a2383f6c0d9 Mon Sep 17 00:00:00 2001 From: TheMisfit68 Date: Mon, 18 Dec 2023 16:17:26 +0100 Subject: [PATCH 2/2] Created function key as a a PLC-class en made it uniform with the other PLC-classes --- .../CirtcuitEnabler.swift | 4 +- .../DimmableLight.swift | 19 ++- .../DoorLock.swift | 4 +- .../FunctionKey.swift | 108 ++++++++---------- .../GarageDoor.swift | 2 +- .../ PLCClassAccessoryDelegates/Light.swift | 4 +- .../ PLCClassAccessoryDelegates/Outlet.swift | 4 +- .../SmartSprinkler.swift | 2 +- .../ToggleableOutlet.swift | 4 +- .../WindowCovering.swift | 2 +- .../MilightAccessoryDelegate.swift | 15 ++- HAPiNest.xcodeproj/project.pbxproj | 4 + HAPiNest/AccessoryNames.xcstrings | 2 + HAPiNest/Localizable.xcstrings | 10 ++ HAPiNest/ServiceNames.xcstrings | 10 ++ MainConfiguration.swift | 8 +- 16 files changed, 110 insertions(+), 92 deletions(-) diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/CirtcuitEnabler.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/CirtcuitEnabler.swift index 119bae77..4cf1c634 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/CirtcuitEnabler.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/CirtcuitEnabler.swift @@ -16,7 +16,7 @@ import JVCocoa // MARK: - PLC level class class CirtcuitEnabler:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulateable{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.Lightbulb var characteristicChanged:Bool = false @@ -49,7 +49,7 @@ class CirtcuitEnabler:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulateab outputSignal.logicalValue = puls } - // MARK: - Processing + // MARK: - PLC Processing public func runCycle(){ reevaluate(&powerState, characteristic:accessory.lightbulb.powerState, hardwareFeedback: hardwarePowerState) diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/DimmableLight.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/DimmableLight.swift index 434c2ab6..cb8c0f89 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/DimmableLight.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/DimmableLight.swift @@ -14,11 +14,18 @@ import IOTypes import JVCocoa // MARK: - PLC level class -class DimmableLight:PLCClassAccessoryDelegate{ - - // Accessory binding +class DimmableLight:PLCClassAccessoryDelegate, DimmedLight{ + + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.Lightbulb var characteristicChanged: Bool = false + + var brightnessTimer: BrightnessTimer! + + override init(){ + super.init() + self.brightnessTimer = BrightnessTimer(dimmer: self) + } // MARK: - State var powerState:Bool? = nil @@ -41,14 +48,13 @@ class DimmableLight:PLCClassAccessoryDelegate{ var brightness:Int? = nil{ didSet{ if let brightness = brightness, brightness != oldValue{ - + if brightness > switchOffLevelDimmer{ previousOnLevel = brightness }else{ powerState?.reset() } - } } } @@ -77,10 +83,11 @@ class DimmableLight:PLCClassAccessoryDelegate{ outputSignal.scaledValue = Float(powerState == true ? (brightness ?? switchOffLevelDimmer+1) : 0) } - // MARK: - Processing + // MARK: - PLC Processing public func runCycle() { reevaluate(&powerState, initialValue: (hardwareBrightness ?? 0 > switchOffLevelDimmer), characteristic:accessory.lightbulb.powerState, hardwareFeedback: nil) + reevaluate(&brightness, characteristic:accessory.lightbulb.brightness, hardwareFeedback:hardwareBrightness) characteristicChanged.reset() diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/DoorLock.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/DoorLock.swift index fad0ed6d..a04c976e 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/DoorLock.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/DoorLock.swift @@ -16,7 +16,7 @@ import JVCocoa // MARK: - PLC level class class Doorlock:PLCClassAccessoryDelegate, PulsOperatedCircuit{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.LockMechanism var characteristicChanged:Bool = false @@ -43,9 +43,7 @@ class Doorlock:PLCClassAccessoryDelegate, PulsOperatedCircuit{ } public func assignOutputParameters(){ - outputSignal.logicalValue = puls - } // MARK: - PLC Processing diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift index d98be184..62f68c5d 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/FunctionKey.swift @@ -16,79 +16,61 @@ import IOTypes import JVCocoa -/// A PLC-Class type object that is not an Accessory-Delegate -/// because it has no Accessory associated with it, -/// it only processes hardware-signals class FunctionKey:PLCClassAccessoryDelegate{ + // MARK: - Accessory binding + typealias AccessorySubclass = Accessory.StatelessProgrammableSwitch var characteristicChanged: Bool = false - var hardwareFeedbackChanged: Bool = false - - private var inputPuls:Bool = false - private var inputTriggered:EBool - - var clicked:Bool = false{ - didSet{ - if clicked{ -#warning("DEBUGPRINT") // TODO: - remove temp print statement - print("🐞\tClicked") - } - clicked.reset() - } + // MARK: - State + private enum SwitchEvent:UInt8{ + case singlePress = 0 + case doublePress = 1 + case longPress = 2 } - let doubleclikInterval:TimeInterval - let doubleClickTimer:DigitalTimer - var doubleClicked:Bool = false{ + private var clicksCounter:Int = 0 + private var switchEvent:SwitchEvent? = nil{ + didSet{ - if doubleClicked{ -#warning("DEBUGPRINT") // TODO: - remove temp print statement - print("🐞\tDoubleClicked") - } - doubleClicked.reset() + clicksCounter = 0 + longPressTimer.reset() + doubleClickTimer.reset() } } - let longPressTime:TimeInterval - let longPressTimer:DigitalTimer - var longPressed:Bool = false{ - didSet{ - if longPressed{ -#warning("DEBUGPRINT") // TODO: - remove temp print statement - print("🐞\tPressedlong") - } - longPressed.reset() - } - } + private var inputPuls:Bool = false + private var inputTriggered:EBool + + private let doubleclikInterval:TimeInterval = 10.0 + private let doubleClickTimer:DigitalTimer + + private let longPressTime:TimeInterval = 20.0 + private let longPressTimer:DigitalTimer - override init(){ + // Hardware feedback state + // Function keys only have inputs, no controlable outputs and therefore also no associated hardwarefeedback + var hardwareFeedbackChanged:Bool = false + + override init(){ - self.inputTriggered = EBool(&inputPuls) - - self.doubleclikInterval = 1.0 + inputTriggered = EBool(&inputPuls) self.doubleClickTimer = DigitalTimer.OffDelay(time: doubleclikInterval) - - self.longPressTime = 2.0 self.longPressTimer = DigitalTimer.OnDelay(time: longPressTime) super.init() } + // MARK: - IO-Signal assignment var inputSignal:DigitalInputSignal{ - let ioSymbol:SoftPLC.IOSymbol = .functionKey(circuit:String(localized: "\(instanceName)", table:"AccessoryNames")) + let ioSymbol:SoftPLC.IOSymbol = .functionKey(circuit:String(localized: "\(instanceName)")) return plc.signal(ioSymbol:ioSymbol) as! DigitalInputSignal } + // MARK: - PLC Parameter assignment public func assignInputParameters(){ - - if let hardwarePuls = inputSignal.logicalValue{ - inputPuls = hardwarePuls - }else{ - inputPuls = false - } - + inputPuls = inputSignal.logicalValue ?? false } public func assignOutputParameters(){ @@ -98,24 +80,24 @@ class FunctionKey:PLCClassAccessoryDelegate{ // MARK: - PLC Processing public func runCycle() { - let risingEdge = inputTriggered.🔼 + doubleClickTimer.input = inputPuls + longPressTimer.input = inputPuls - if risingEdge && !doubleClickTimer.output{ - clicked.set() - }else if risingEdge && doubleClickTimer.output{ - doubleClicked.set() - }else if longPressTimer.output{ - longPressed.set() + if longPressTimer.output{ + switchEvent = .longPress + }else if (clicksCounter >= 2) { + switchEvent = .doublePress + }else if (clicksCounter == 1) && !doubleClickTimer.output{ + switchEvent = .singlePress } -// reevaluate(&clicked, characteristic:accessory.programmableSwitchEvent, hardwareFeedback: hardwarePowerState) -// reevaluate(&doubleClicked, characteristic:accessory.outlet.powerState, hardwareFeedback: hardwarePowerState) - - - - doubleClickTimer.input = inputPuls - longPressTimer.input = inputPuls + if inputTriggered.🔼 { + clicksCounter += 1 + }else if !doubleClickTimer.output{ + clicksCounter = 0 + } + reevaluate(&switchEvent, characteristic:accessory.primaryService.programmableSwitchEvent, hardwareFeedback: nil) } } diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/GarageDoor.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/GarageDoor.swift index af25204d..38c866a6 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/GarageDoor.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/GarageDoor.swift @@ -16,7 +16,7 @@ import JVCocoa // MARK: - PLC level class class GarageDoor:PLCClassAccessoryDelegate, PulsOperatedCircuit{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.GarageDoorOpener.StatelessGarageDoorOpener var characteristicChanged: Bool = false diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/Light.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/Light.swift index 1bf9830f..1fd179fe 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/Light.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/Light.swift @@ -17,7 +17,7 @@ import OSLog // MARK: - PLC level class class Light:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulateable{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.Lightbulb var characteristicChanged:Bool = false @@ -50,7 +50,7 @@ class Light:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulateable{ outputSignal.logicalValue = puls } - // MARK: - Processing + // MARK: - PLC Processing public func runCycle(){ reevaluate(&powerState, characteristic:accessory.lightbulb.powerState, hardwareFeedback: hardwarePowerState) diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/Outlet.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/Outlet.swift index 77f66085..f71b5ca6 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/Outlet.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/Outlet.swift @@ -16,7 +16,7 @@ import JVCocoa // MARK: - PLC level class class Outlet:PLCClassAccessoryDelegate{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.Outlet var characteristicChanged: Bool = false @@ -58,7 +58,7 @@ class Outlet:PLCClassAccessoryDelegate{ outputSignal.logicalValue = powerState ?? false } - // MARK: - Processing + // MARK: - PLC Processing public func runCycle() { reevaluate(&powerState, characteristic:accessory.outlet.powerState, hardwareFeedback: hardwarePowerState) diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/SmartSprinkler.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/SmartSprinkler.swift index 26715da8..59214e93 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/SmartSprinkler.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/SmartSprinkler.swift @@ -19,7 +19,7 @@ import OSLog // MARK: - PLC level class class SmartSprinkler:PLCClassAccessoryDelegate{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.SmartSprinkler var characteristicChanged:Bool = false diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/ToggleableOutlet.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/ToggleableOutlet.swift index 165995c7..441a1452 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/ToggleableOutlet.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/ToggleableOutlet.swift @@ -16,7 +16,7 @@ import JVCocoa // MARK: - PLC level class class ToggleableOutlet:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulateable{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.Outlet var characteristicChanged:Bool = false @@ -57,7 +57,7 @@ class ToggleableOutlet:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulatea } - // MARK: - Processing + // MARK: - PLC Processing public func runCycle() { reevaluate(&powerState, characteristic:accessory.outlet.powerState, hardwareFeedback: hardwarePowerState) diff --git a/Accessory Delegates/ PLCClassAccessoryDelegates/WindowCovering.swift b/Accessory Delegates/ PLCClassAccessoryDelegates/WindowCovering.swift index 14ede96b..25f8afb2 100644 --- a/Accessory Delegates/ PLCClassAccessoryDelegates/WindowCovering.swift +++ b/Accessory Delegates/ PLCClassAccessoryDelegates/WindowCovering.swift @@ -16,7 +16,7 @@ import JVCocoa // MARK: - PLC level class class WindowCovering:PLCClassAccessoryDelegate, PulsOperatedCircuit, Simulateable{ - // Accessory binding + // MARK: - Accessory binding typealias AccessorySubclass = Accessory.WindowCovering var characteristicChanged:Bool = false diff --git a/Accessory Delegates/MilightAccessoryDelegate.swift b/Accessory Delegates/MilightAccessoryDelegate.swift index 8bd93ea3..657e5b04 100644 --- a/Accessory Delegates/MilightAccessoryDelegate.swift +++ b/Accessory Delegates/MilightAccessoryDelegate.swift @@ -15,8 +15,10 @@ import OSLog /// Handles characteristic changes for a Homekit Accessory. /// It uses the MilightDriver to pass those changes to the hardware -class MilightAccessoryDelegate:MilightDriverV6, AccessoryDelegate { - +class MilightAccessoryDelegate:MilightDriverV6, AccessoryDelegate, DimmedLight { + + var brightnessTimer: BrightnessTimer! + let zone:MilightDriver.Zone var name: String{ return zone.name @@ -25,11 +27,12 @@ class MilightAccessoryDelegate:MilightDriverV6, AccessoryDelegate { init(ipAddress: String, zone:MilightDriver.Zone){ self.zone = zone super.init(ipAddress: ipAddress) + self.brightnessTimer = BrightnessTimer(dimmer: self) } var characteristicChanged: Bool = false - var brightness:Int = 100{ + var brightness:Int? = 100{ didSet{ executeCommand(mode: .rgbwwcw, action: .brightNess, value: brightness, zone: zone) } @@ -66,7 +69,7 @@ class MilightAccessoryDelegate:MilightDriverV6, AccessoryDelegate { } } } - + func handleCharacteristicChange(accessory:Accessory, service: Service, characteristic: GenericCharacteristic, @@ -82,7 +85,9 @@ class MilightAccessoryDelegate:MilightDriverV6, AccessoryDelegate { case CharacteristicType.brightness: - brightness = characteristic.value as! Int +// brightness = characteristic.value as! Int + self.brightnessTimer.timeFor100percentChange = 1800 + self.brightnessTimer.targetBrightness = (characteristic.value as! Int) case CharacteristicType.hue: diff --git a/HAPiNest.xcodeproj/project.pbxproj b/HAPiNest.xcodeproj/project.pbxproj index 29300562..13b5af42 100644 --- a/HAPiNest.xcodeproj/project.pbxproj +++ b/HAPiNest.xcodeproj/project.pbxproj @@ -44,6 +44,7 @@ DC9963892AD3073000915EAC /* CirtcuitEnabler.swift in Sources */ = {isa = PBXBuildFile; fileRef = DC9963882AD3073000915EAC /* CirtcuitEnabler.swift */; }; DCA37CF926BB29EF003CC3BF /* HAPTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA37CF826BB29EF003CC3BF /* HAPTests.swift */; }; DCA3DF312B28D97000554A8A /* BrightnessTimer.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCA3DF302B28D97000554A8A /* BrightnessTimer.swift */; }; + DCA626B12B3083C900BBDD91 /* ServiceNames.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = DCA626B02B3083C900BBDD91 /* ServiceNames.xcstrings */; }; DCAB996A2A816734005FCC29 /* README.md in Resources */ = {isa = PBXBuildFile; fileRef = DCAB99692A816734005FCC29 /* README.md */; }; DCBBC7082B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBBC7072B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift */; }; DCBCFB5529678657000F0376 /* Enums.swift in Sources */ = {isa = PBXBuildFile; fileRef = DCBCFB5429678657000F0376 /* Enums.swift */; }; @@ -115,6 +116,7 @@ DCA37CF626BB29EF003CC3BF /* HAPiNestTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = HAPiNestTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; }; DCA37CF826BB29EF003CC3BF /* HAPTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HAPTests.swift; sourceTree = ""; }; DCA3DF302B28D97000554A8A /* BrightnessTimer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BrightnessTimer.swift; sourceTree = ""; }; + DCA626B02B3083C900BBDD91 /* ServiceNames.xcstrings */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.json.xcstrings; path = ServiceNames.xcstrings; sourceTree = ""; }; DCAB99692A816734005FCC29 /* README.md */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = net.daringfireball.markdown; path = README.md; sourceTree = ""; }; DCBBC7072B2EE4D80005EE6E /* StatelessProgrammableSwitch.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StatelessProgrammableSwitch.swift; sourceTree = ""; }; DCBCFB5429678657000F0376 /* Enums.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Enums.swift; sourceTree = ""; }; @@ -202,6 +204,7 @@ DC54B6C12570586E00D9169F /* Assets.xcassets */, DC4D66792A956AC1004C9D30 /* Localizable.xcstrings */, DC4D667B2A9571BA004C9D30 /* AccessoryNames.xcstrings */, + DCA626B02B3083C900BBDD91 /* ServiceNames.xcstrings */, DCF7D5AB2AD0D106000010AA /* TVChannelNames.xcstrings */, DC90DA6A2732828200068839 /* MainWindow */, DC90DA5D2732817000068839 /* PreferencesWindow */, @@ -468,6 +471,7 @@ DCAB996A2A816734005FCC29 /* README.md in Resources */, DC54B6C22570586E00D9169F /* Assets.xcassets in Resources */, DC4D667A2A956AC1004C9D30 /* Localizable.xcstrings in Resources */, + DCA626B12B3083C900BBDD91 /* ServiceNames.xcstrings in Resources */, DC4D667C2A9571BA004C9D30 /* AccessoryNames.xcstrings in Resources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/HAPiNest/AccessoryNames.xcstrings b/HAPiNest/AccessoryNames.xcstrings index 90bfd7e3..825c31b7 100644 --- a/HAPiNest/AccessoryNames.xcstrings +++ b/HAPiNest/AccessoryNames.xcstrings @@ -2,6 +2,7 @@ "sourceLanguage" : "en", "strings" : { "%@" : { + "extractionState" : "stale", "localizations" : { "nl" : { "stringUnit" : { @@ -162,6 +163,7 @@ } }, "Electric Car" : { + "extractionState" : "stale", "localizations" : { "nl" : { "stringUnit" : { diff --git a/HAPiNest/Localizable.xcstrings b/HAPiNest/Localizable.xcstrings index 818b2c77..ae65b63a 100644 --- a/HAPiNest/Localizable.xcstrings +++ b/HAPiNest/Localizable.xcstrings @@ -11,6 +11,16 @@ } } }, + "%@" : { + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "%@" + } + } + } + }, "Are you sure?" : { "localizations" : { "nl" : { diff --git a/HAPiNest/ServiceNames.xcstrings b/HAPiNest/ServiceNames.xcstrings index 6b4f9a2b..3be8599c 100644 --- a/HAPiNest/ServiceNames.xcstrings +++ b/HAPiNest/ServiceNames.xcstrings @@ -21,6 +21,16 @@ } } }, + "Function key" : { + "localizations" : { + "nl" : { + "stringUnit" : { + "state" : "translated", + "value" : "Functietoets" + } + } + } + }, "Manual" : { "localizations" : { "nl" : { diff --git a/MainConfiguration.swift b/MainConfiguration.swift index 07ddd799..90177a66 100644 --- a/MainConfiguration.swift +++ b/MainConfiguration.swift @@ -40,10 +40,10 @@ struct MainConfiguration{ static let Accessories:[Accessory : any AccessoryDelegate] = [ // Function Keys - Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Frontdoor", table:"AccessoryNames"), serialNumber: "40000")) : PLCAccessoryDelegate(), - Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Left side bed", table:"AccessoryNames"), serialNumber: "40001")) : PLCAccessoryDelegate(), - Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Right side bed", table:"AccessoryNames"), serialNumber: "40002")) : PLCAccessoryDelegate(), - Accessory.ProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Landing", table:"AccessoryNames"), serialNumber: "40003")) : PLCAccessoryDelegate(), + Accessory.StatelessProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Frontdoor", table:"AccessoryNames"), serialNumber: "50000")) : PLCAccessoryDelegate(), + Accessory.StatelessProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Left side bed", table:"AccessoryNames"), serialNumber: "40001")) : PLCAccessoryDelegate(), + Accessory.StatelessProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Right side bed", table:"AccessoryNames"), serialNumber: "40002")) : PLCAccessoryDelegate(), + Accessory.StatelessProgrammableSwitch(info: Service.Info(name:String(localized:"Function Key Landing", table:"AccessoryNames"), serialNumber: "40003")) : PLCAccessoryDelegate(), // MARK: - Dimmable Lights