Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
lgrachov committed Aug 30, 2024
0 parents commit 7b4e1c5
Show file tree
Hide file tree
Showing 7 changed files with 1,387 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
SMARTTHINGS_PAT="Your SmartThings personal access token here!"
SMARTTHINGS_DEVICE_NAME="The name of the device that you want to control."
MAC_ADDRESS="A MAC Address."
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# SmartThings TV HomeKit

A simple HomeKit accessory made using HAP-NodeJS to make your SmartThings TV into a switch that can be controlled from HomeKit.

## Usage

### Setting up the `.env` file

In order to use this accessory, you need to setup the environment variables.

#### Setting up a SmartThings Personal Access Token

The first step is, you have to generate a SmartThings Personal Access Token. Generate a SmartThings Personal Access Token [here,](https://account.smartthings.com/tokens), and add this line to your `.env` file:

```env
SMARTTHINGS_PAT="Your SmartThings personal access token here!"
```

#### The last step, enter the device name

Instead of copying a device ID from SmartThings, this accessory finds a device with the name that you entered and automatically retrieves its device ID! So, all you need to do is add this line to your `.env`:

```env
SMARTTHINGS_DEVICE_NAME="The name of the device that you want to control."
```

For example, if your TV is named Kitchen TV (not including the room), then you need to add this to your `.env`:

```env
SMARTTHINGS_DEVICE_NAME="Kitchen TV"
```

### Starting the accessory

Now, you need to start the accessory. In order to do this, you need to install all the dependencies using npm. All you need to do is run `npm i`, and it will automatically install all of the dependencies.

> [!NOTE]
> The MAC Address is changed each time if a MAC Address is not specified in the `.env` file. To specify a MAC Address, you first have to generate a MAC Address using this [JSFiddle](https://jsfiddle.net/guest271314/qhbC9/) or by using [Browserling's MAC Address generator,](https://www.browserling.com/tools/random-mac) and then add this line to your `.env`:
>
> ```env
> MAC_ADDRESS="Your generated > MAC Address"
> ```
After that, you just need to run `npm start`.

### Adding the accessory to HomeKit

All that’s left to do is add the accessory to HomeKit. The default setup code is 141-91-495, but you can change it in the code. In order to type the setup code, you need to follow the steps:

1. You first have to choose **Add Accessory**.
2. Click on **More options...**.
3. Choose the accessory with the name that you chose during the configuration process.
4. Enter the setup code, and configure the accessory.

Ta-da! Your accessory is now ready to go!

## Two switches?

Yes! This accessory comes with two switches, one that controls the power, and a second one which controls the mute state!

## Known issues

There are a bit of bugs in this project, but check the known issues first before reporting an issue!

### The accessory is running, did not give any errors, but does not show up in HomeKit!

If you removed the accessory and you are trying to re-add it, you will have to reset the MAC Address to add it back again.
75 changes: 75 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import 'dotenv/config';
import * as hap from 'hap-nodejs';
import { getDeviceByName, executeCommand } from './src/smartthingsApi.js';
import { generateMacAddress } from './src/network.js';
const tv = await getDeviceByName(process.env.SMARTTHINGS_DEVICE_NAME);
const deviceId = tv.deviceId;
const Accessory = hap.Accessory;
const Characteristic = hap.Characteristic;
const CharacteristicEventTypes = hap.CharacteristicEventTypes;
const Service = hap.Service;

const accessoryUuid = hap.uuid.generate('smartthings.tv');
const accessory = new Accessory(
process.env.SMARTTHINGS_DEVICE_NAME,
accessoryUuid
);
const powerService = new Service.Switch();
powerService.name = 'Power';
const muteService = new Service.Switch();
muteService.name = 'Mute';
muteService.subtype = 'audioMute';
let currentTVPower = true;
let commandTVPower = 'on';
let muteTV = false;
let commandMuteTV = 'unmuted';
const powerCharacteristic = powerService.getCharacteristic(Characteristic.On);
const muteCharacteristic = muteService.getCharacteristic(Characteristic.On);

powerCharacteristic.on(
CharacteristicEventTypes.SET,
async (value, callback) => {
console.log('Setting TV power state to: ' + value);
currentTVPower = value;
if (value == true) {
commandTVPower = 'on';
} else {
commandTVPower = 'off';
}
await executeCommand(deviceId, 'switch', 'main', commandTVPower, []);
callback();
}
);

muteCharacteristic.on(CharacteristicEventTypes.SET, async (value, callback) => {
console.log('Setting TV mute state to: ' + value);
muteTV = value;
if (value == true) {
commandMuteTV = 'mute';
} else {
commandMuteTV = 'unmute';
}
await executeCommand(deviceId, 'audioMute', 'main', commandMuteTV, []);
callback();
});
powerService.name = 'Power';
accessory.addService(powerService);

muteService.name = 'Mute';
accessory.addService(muteService);

let username = '';
if (process.env.MAC_ADDRESS === undefined) {
username = generateMacAddress();
} else {
username = process.env.MAC_ADDRESS;
}
accessory.publish({
username,
pincode: '141-91-495',
port: 458,
category: hap.Categories.TELEVISION,
});

console.log('Accessory ready!');
console.log(`Setup code is 141-91-495`);
Loading

0 comments on commit 7b4e1c5

Please sign in to comment.