Compare commits
	
		
			12 Commits
		
	
	
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 4e1dce3e32 | |||
| 2f030fa08c | |||
|  | bfba6e47d1 | ||
|  | 28abf136b7 | ||
|  | ed652b2f76 | ||
|  | 0846a72931 | ||
|  | f1d1da0945 | ||
|  | 76438d6811 | ||
|  | 7971fd3ec1 | ||
|  | 3fe902c50b | ||
|  | 52a259dafd | ||
|  | 128bb933bd | 
							
								
								
									
										80
									
								
								.drone.yml
									
									
									
									
									
								
							
							
						
						
									
										80
									
								
								.drone.yml
									
									
									
									
									
								
							| @@ -1,80 +0,0 @@ | |||||||
| kind: pipeline |  | ||||||
| type: docker |  | ||||||
| name: default |  | ||||||
|  |  | ||||||
| clone: |  | ||||||
|   disable: true |  | ||||||
|  |  | ||||||
| steps: |  | ||||||
|   - name: clone |  | ||||||
|     image: alpine/git |  | ||||||
|     commands: |  | ||||||
|       - git clone https://gitea.watsonlabs.net/watsonb8/homebridge-harmony-control.git . |  | ||||||
|       - git checkout $DRONE_COMMIT |  | ||||||
|  |  | ||||||
|   - name: build |  | ||||||
|     image: node |  | ||||||
|     commands: |  | ||||||
|       - npm install |  | ||||||
|       - npm run build |  | ||||||
|  |  | ||||||
|   - name: version |  | ||||||
|     image: node |  | ||||||
|     commands: |  | ||||||
|       - export version=`node -p "require('./package.json').version"` |  | ||||||
|       - export commit=`echo $DRONE_COMMIT | cut -c1-5` |  | ||||||
|       - npm version prerelease --preid=$commit --git-tag-version=false --allow-same-version=true |  | ||||||
|     when: |  | ||||||
|       event: |  | ||||||
|         exclude: |  | ||||||
|           - tag |  | ||||||
|           - pull_request |  | ||||||
|       branch: |  | ||||||
|         include: |  | ||||||
|           - master |  | ||||||
|  |  | ||||||
|   - name: publish pre |  | ||||||
|     image: plugins/npm |  | ||||||
|     settings: |  | ||||||
|       username: |  | ||||||
|         from_secret: npm_username |  | ||||||
|       password: |  | ||||||
|         from_secret: npm_password |  | ||||||
|       email: brandon@watsonlabs.net |  | ||||||
|       registry: "http://10.44.1.6:4873/" |  | ||||||
|     when: |  | ||||||
|       event: |  | ||||||
|         exclude: |  | ||||||
|           - tag |  | ||||||
|           - pull_request |  | ||||||
|       branch: |  | ||||||
|         include: |  | ||||||
|           - master |  | ||||||
|  |  | ||||||
|   - name: publish tagged version |  | ||||||
|     image: plugins/npm |  | ||||||
|     settings: |  | ||||||
|       username: |  | ||||||
|         from_secret: npm_username |  | ||||||
|       password: |  | ||||||
|         from_secret: npm_password |  | ||||||
|       email: brandon@watsonlabs.net |  | ||||||
|       registry: "http://10.44.1.6:4873/" |  | ||||||
|     when: |  | ||||||
|       event: |  | ||||||
|         - tag |  | ||||||
|       exclude: |  | ||||||
|         - pull_request |  | ||||||
|  |  | ||||||
|   - name: Notify |  | ||||||
|     image: drillster/drone-email |  | ||||||
|     settings: |  | ||||||
|       host: 10.44.1.13 |  | ||||||
|       username: srvGitea |  | ||||||
|       password: |  | ||||||
|         from_secret: smtp_password |  | ||||||
|       from: drone@watsonlabs.net |  | ||||||
|       skip_verify: true |  | ||||||
|     when: |  | ||||||
|       status: |  | ||||||
|         - failure |  | ||||||
							
								
								
									
										82
									
								
								.gitea/workflows/ci.yaml
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										82
									
								
								.gitea/workflows/ci.yaml
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,82 @@ | |||||||
|  | name: Build homebridge-harmony-control | ||||||
|  | on:  | ||||||
|  |   workflow_dispatch: | ||||||
|  |   push: | ||||||
|  |     branches: | ||||||
|  |       - master | ||||||
|  |  | ||||||
|  | jobs: | ||||||
|  |   build: | ||||||
|  |     name: Build | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v4 | ||||||
|  |       - uses: actions/setup-node@v4 | ||||||
|  |         with: | ||||||
|  |           node-version: 18 | ||||||
|  |       - run: | | ||||||
|  |           npm ci | ||||||
|  |           npm run build | ||||||
|  |  | ||||||
|  |   version: | ||||||
|  |     name: Version | ||||||
|  |     outputs: | ||||||
|  |       version: ${{ steps.get_version.outputs.version }} | ||||||
|  |       commit: ${{ steps.get_version.outputs.commit }} | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v4 | ||||||
|  |       - uses: actions/setup-node@v4 | ||||||
|  |         with: | ||||||
|  |           node-version: 18 | ||||||
|  |       - id: get_version | ||||||
|  |         name: Set Version | ||||||
|  |         run: | | ||||||
|  |           export version=`node -p "require('./package.json').version"` | ||||||
|  |           export commit=`echo $GITHUB_SHA | cut -c1-5` | ||||||
|  |           echo "version=$version" >> "$GITHUB_OUTPUT" | ||||||
|  |           echo "commit=$commit" >> "$GITHUB_OUTPUT" | ||||||
|  |  | ||||||
|  |   publish_tagged: | ||||||
|  |     name: Publish Latest | ||||||
|  |     needs:  | ||||||
|  |       - build | ||||||
|  |       - version | ||||||
|  |     steps: | ||||||
|  |       - uses: actions/checkout@v4 | ||||||
|  |       - uses: actions/setup-node@v4 | ||||||
|  |       - run: npm config set @watsonb8:registry https://gitea.watsonlabs.net/api/packages/watsonb8/npm/ | ||||||
|  |       - name: Publish | ||||||
|  |         env: | ||||||
|  |           NPM_TOKEN: ${{ secrets.NPM_TOKEN }} | ||||||
|  |           COMMIT: ${{ needs.version.outputs.commit }} | ||||||
|  |         run: | | ||||||
|  |           npm ci | ||||||
|  |           npm config set -- '//gitea.watsonlabs.net/api/packages/watsonb8/npm/:_authToken' "$NPM_TOKEN" | ||||||
|  |           npm version prerelease --preid="$COMMIT" --git-tag-version=false --allow-same-version=true | ||||||
|  |           npm publish | ||||||
|  |    | ||||||
|  |   deploy: | ||||||
|  |     runs-on:  | ||||||
|  |       - ubuntu-latest | ||||||
|  |       - internal | ||||||
|  |     name: Deploy | ||||||
|  |     needs: publish_tagged | ||||||
|  |     steps: | ||||||
|  |       - name: Set up SSH key | ||||||
|  |         run: | | ||||||
|  |           mkdir -p ~/.ssh | ||||||
|  |           echo "${{ secrets.ELEVATED_HOMEBRIDGE_SSH_KEY }}" > ~/.ssh/id_rsa | ||||||
|  |           chmod 600 ~/.ssh/id_rsa | ||||||
|  |           ssh-keyscan -p 22 homebridge.me >> ~/.ssh/known_hosts | ||||||
|  |           sudo apt update | ||||||
|  |           sudo apt install sshpass | ||||||
|  |  | ||||||
|  |       - name: Remove old Package | ||||||
|  |         run: | | ||||||
|  |           sshpass -p '${{ secrets.ELEVATED_HOMEBRIDGE_PASSWORD }}' ssh -v -o StrictHostKeyChecking=no ${{ secrets.ELEVATED_HOMEBRIDGE_USER }}@${{ secrets.HOMEBRIDGE_HOST }} <<'ENDSSH' | ||||||
|  |           rm -r /home/${{ secrets.HOMEBRIDGE_USER }}/.npm-global/lib/node_modules/@watsonb8/homebridge-harmony-control | ||||||
|  |           ENDSSH | ||||||
|  |       - name: Deploy | ||||||
|  |         run: | | ||||||
|  |           sshpass -p '${{ secrets.ELEVATED_HOMEBRIDGE_PASSWORD }}' ssh -v -o StrictHostKeyChecking=no ${{ secrets.ELEVATED_HOMEBRIDGE_USER }}@${{ secrets.HOMEBRIDGE_HOST }} <<'ENDSSH' | ||||||
|  |           npm install -g @watsonb8/homebridge-harmony-control | ||||||
|  |           ENDSSH | ||||||
							
								
								
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							| @@ -1,6 +1,6 @@ | |||||||
| { | { | ||||||
|   "name": "@watsonb8/homebridge-harmony-control", |   "name": "@watsonb8/homebridge-harmony-control", | ||||||
|   "version": "1.2.0", |   "version": "1.2.3", | ||||||
|   "lockfileVersion": 1, |   "lockfileVersion": 1, | ||||||
|   "requires": true, |   "requires": true, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|   | |||||||
| @@ -1,10 +1,10 @@ | |||||||
| { | { | ||||||
|     "name": "@watsonb8/homebridge-harmony-control", |     "name": "@watsonb8/homebridge-harmony-control", | ||||||
|     "version": "1.2.0", |     "version": "1.3.0", | ||||||
|     "description": "Homebridge platform to control smart home equipment by room.", |     "description": "Homebridge platform to control smart home equipment by room.", | ||||||
|     "main": "bin/index.js", |     "main": "bin/index.js", | ||||||
|     "publishConfig": { |     "publishConfig": { | ||||||
|         "registry": "http://10.44.1.6:4873/" |         "registry": "https://gitea.watsonlabs.net" | ||||||
|     }, |     }, | ||||||
|     "scripts": { |     "scripts": { | ||||||
|         "build": "tsc --build", |         "build": "tsc --build", | ||||||
| @@ -44,4 +44,4 @@ | |||||||
|         "request": "^2.88.0", |         "request": "^2.88.0", | ||||||
|         "tsyringe": "^4.6.0" |         "tsyringe": "^4.6.0" | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -137,7 +137,10 @@ export class ControlUnit { | |||||||
|         break; |         break; | ||||||
|       //Turn on with first activity |       //Turn on with first activity | ||||||
|       case 1: |       case 1: | ||||||
|         this._activityService.startActivity( |         if (this._activityService.getIsActive(this._accessory.displayName)) { | ||||||
|  |           break; | ||||||
|  |         } | ||||||
|  |         this._activityService.startLastOrDefaultActivity( | ||||||
|           this._accessory.displayName, |           this._accessory.displayName, | ||||||
|           this._activities[0] |           this._activities[0] | ||||||
|         ); |         ); | ||||||
| @@ -150,7 +153,8 @@ export class ControlUnit { | |||||||
|    */ |    */ | ||||||
|   private onGetAccessoryActive = async () => { |   private onGetAccessoryActive = async () => { | ||||||
|     //@ts-ignore |     //@ts-ignore | ||||||
|     return this._activityService.getIsActive(this._accessory.displayName) |     return this._activityService.getCurrentActivity(this._accessory.displayName) | ||||||
|  |       ?.DisplayName | ||||||
|       ? this._platform.Characteristic.Active.ACTIVE |       ? this._platform.Characteristic.Active.ACTIVE | ||||||
|       : this._platform.Characteristic.Active.INACTIVE; |       : this._platform.Characteristic.Active.INACTIVE; | ||||||
|   }; |   }; | ||||||
| @@ -176,7 +180,7 @@ export class ControlUnit { | |||||||
|    * Event handler for GET active identifier characteristic |    * Event handler for GET active identifier characteristic | ||||||
|    */ |    */ | ||||||
|   private onGetActiveIdentifier = async () => { |   private onGetActiveIdentifier = async () => { | ||||||
|     let currentActivity: IActivity = this._activityService.getIsActive( |     let currentActivity: IActivity = this._activityService.getCurrentActivity( | ||||||
|       this._accessory.displayName |       this._accessory.displayName | ||||||
|     )!; |     )!; | ||||||
|     let identifier: number = 0; |     let identifier: number = 0; | ||||||
|   | |||||||
| @@ -9,18 +9,30 @@ export class StateDataProvider { | |||||||
|   } = {}; |   } = {}; | ||||||
|  |  | ||||||
|   public updateState(activity: IActivity, controlUnitName: string): void { |   public updateState(activity: IActivity, controlUnitName: string): void { | ||||||
|     this._states[controlUnitName] = { currentActivity: activity }; |     const oldState = this._states[controlUnitName]; | ||||||
|  |     this._states[controlUnitName] = { | ||||||
|  |       currentActivity: activity, | ||||||
|  |       lastActivity: oldState?.lastActivity, | ||||||
|  |     }; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public deactivateState(controlUnitName: string): void { | ||||||
|  |     const oldState = this._states[controlUnitName]; | ||||||
|  |     this._states[controlUnitName] = { | ||||||
|  |       currentActivity: undefined, | ||||||
|  |       lastActivity: oldState?.currentActivity, | ||||||
|  |     }; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public removeState(controlUnitName: string): void { |   public removeState(controlUnitName: string): void { | ||||||
|     this._states[controlUnitName] = undefined; |     this._states[controlUnitName] = undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public getState(controlUnitName: string) { |   public getState(controlUnitName: string): IActivityState | undefined { | ||||||
|     if (!this._states[controlUnitName]) { |     if (!this._states[controlUnitName]) { | ||||||
|       return undefined; |       return undefined; | ||||||
|     } |     } | ||||||
|     return this._states[controlUnitName]!.currentActivity; |     return this._states[controlUnitName]; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   public get states(): { |   public get states(): { | ||||||
|   | |||||||
| @@ -1,5 +1,6 @@ | |||||||
| import { IActivity } from "./config"; | import { IActivity } from "./config"; | ||||||
|  |  | ||||||
| export interface IActivityState { | export interface IActivityState { | ||||||
|   currentActivity: IActivity; |   currentActivity?: IActivity; | ||||||
|  |   lastActivity?: IActivity; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -22,6 +22,18 @@ export class ActivityService { | |||||||
|     @inject("log") private _log: Logging |     @inject("log") private _log: Logging | ||||||
|   ) {} |   ) {} | ||||||
|  |  | ||||||
|  |   public startLastOrDefaultActivity = async ( | ||||||
|  |     controlUnitName: string, | ||||||
|  |     defaultActivity: IActivity | ||||||
|  |   ) => { | ||||||
|  |     const lastActivity = this.getLastActivity(controlUnitName); | ||||||
|  |     if (!lastActivity) { | ||||||
|  |       return this.startActivity(controlUnitName, defaultActivity); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |     return this.startActivity(controlUnitName, lastActivity); | ||||||
|  |   }; | ||||||
|  |  | ||||||
|   public startActivity = async ( |   public startActivity = async ( | ||||||
|     controlUnitName: string, |     controlUnitName: string, | ||||||
|     activity: IActivity |     activity: IActivity | ||||||
| @@ -68,19 +80,24 @@ export class ActivityService { | |||||||
|     ); |     ); | ||||||
|     await this._harmonyDataProvider.powerOffDevices(devicesToTurnOff); |     await this._harmonyDataProvider.powerOffDevices(devicesToTurnOff); | ||||||
|  |  | ||||||
|     this._stateDataProvider.removeState(controlUnitName); |     this._stateDataProvider.deactivateState(controlUnitName); | ||||||
|   }; |   }; | ||||||
|  |  | ||||||
|   public getCurrentActivity(controlUnitName: string): IActivity | undefined { |   public getCurrentActivity(controlUnitName: string): IActivity | undefined { | ||||||
|     return this._stateDataProvider.getState(controlUnitName); |     return this._stateDataProvider.getState(controlUnitName)?.currentActivity; | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   public getLastActivity(controlUnitName: string): IActivity | undefined { | ||||||
|  |     return this._stateDataProvider.getState(controlUnitName)?.lastActivity; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
|    * Return if a control unit is active |    * Return if a control unit is active | ||||||
|    * @param controlUnitName |    * @param controlUnitName | ||||||
|    */ |    */ | ||||||
|   public getIsActive(controlUnitName: string): IActivity | undefined { |   public getIsActive(controlUnitName: string): boolean { | ||||||
|     return this._stateDataProvider.getState(controlUnitName); |     const state = this._stateDataProvider.getState(controlUnitName); | ||||||
|  |     return state != undefined && state.currentActivity != undefined; | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   /** |   /** | ||||||
| @@ -100,11 +117,11 @@ export class ActivityService { | |||||||
|       let currentOtherState: IActivityState = |       let currentOtherState: IActivityState = | ||||||
|         this._stateDataProvider.states[controlUnitKey]!; |         this._stateDataProvider.states[controlUnitKey]!; | ||||||
|  |  | ||||||
|       if (!currentOtherState) { |       if (!currentOtherState || !currentOtherState.currentActivity) { | ||||||
|         return devicesToTurnOn; |         return devicesToTurnOn; | ||||||
|       } |       } | ||||||
|  |  | ||||||
|       currentOtherState.currentActivity.DeviceSetupList.forEach( |       currentOtherState.currentActivity!.DeviceSetupList.forEach( | ||||||
|         (value: IDeviceSetupItem) => { |         (value: IDeviceSetupItem) => { | ||||||
|           //there are devices to remove |           //there are devices to remove | ||||||
|           if (devicesToTurnOn.some((e) => e && e.name === value.DeviceName)) { |           if (devicesToTurnOn.some((e) => e && e.name === value.DeviceName)) { | ||||||
|   | |||||||
| @@ -24,7 +24,7 @@ export class CommandService { | |||||||
|       let commandName: string = ""; |       let commandName: string = ""; | ||||||
|  |  | ||||||
|       let device: HarmonyDevice = this._harmonyDataProvider.getDeviceByName( |       let device: HarmonyDevice = this._harmonyDataProvider.getDeviceByName( | ||||||
|         currentActivity.ControlDevice |         currentActivity.currentActivity!.ControlDevice | ||||||
|       ); |       ); | ||||||
|       switch (key) { |       switch (key) { | ||||||
|         case RemoteKey.ARROW_UP: { |         case RemoteKey.ARROW_UP: { | ||||||
|   | |||||||
| @@ -16,10 +16,12 @@ export class VolumeService { | |||||||
|    */ |    */ | ||||||
|   public volumeUp = async (controlUnitName: string) => { |   public volumeUp = async (controlUnitName: string) => { | ||||||
|     let volumeUpCommand: string = "Volume Up"; |     let volumeUpCommand: string = "Volume Up"; | ||||||
|     let currentActivity = this._stateDataProvider.getState(controlUnitName); |     let currentState = this._stateDataProvider.getState(controlUnitName); | ||||||
|     if (currentActivity) { |     if (currentState) { | ||||||
|       let volumeDevice: HarmonyDevice = |       let volumeDevice: HarmonyDevice = | ||||||
|         this._harmonyDataProvider.getDeviceByName(currentActivity.VolumeDevice); |         this._harmonyDataProvider.getDeviceByName( | ||||||
|  |           currentState.currentActivity!.VolumeDevice | ||||||
|  |         ); | ||||||
|       await this._harmonyDataProvider.sendCommand( |       await this._harmonyDataProvider.sendCommand( | ||||||
|         volumeUpCommand, |         volumeUpCommand, | ||||||
|         volumeDevice |         volumeDevice | ||||||
| @@ -32,10 +34,12 @@ export class VolumeService { | |||||||
|    */ |    */ | ||||||
|   public volumeDown = async (controlUnitName: string) => { |   public volumeDown = async (controlUnitName: string) => { | ||||||
|     let volumeDownCommand: string = "Volume Down"; |     let volumeDownCommand: string = "Volume Down"; | ||||||
|     let currentActivity = this._stateDataProvider.getState(controlUnitName); |     let currentState = this._stateDataProvider.getState(controlUnitName); | ||||||
|     if (currentActivity) { |     if (currentState) { | ||||||
|       let volumeDevice: HarmonyDevice = |       let volumeDevice: HarmonyDevice = | ||||||
|         this._harmonyDataProvider.getDeviceByName(currentActivity.VolumeDevice); |         this._harmonyDataProvider.getDeviceByName( | ||||||
|  |           currentState.currentActivity!.VolumeDevice | ||||||
|  |         ); | ||||||
|       await this._harmonyDataProvider.sendCommand( |       await this._harmonyDataProvider.sendCommand( | ||||||
|         volumeDownCommand, |         volumeDownCommand, | ||||||
|         volumeDevice |         volumeDevice | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user