Outdoor door / gate sensor ?

This forum is for generic questions about devices. Note: if your question is specific to a Z-Wave, INSTEON, Virtual, or X10 device, please use the correct sub forum from the Built-in Interfaces/Technologies section.
User avatar
norcoscia
Posts: 1228
Joined: Wed Sep 09, 2015 5:54 am

Re: Outdoor door / gate sensor ?

Post by norcoscia »

OK - now you’re just showing off :lol:
_______
Norm
ryanbuckner
Posts: 1107
Joined: Sat Oct 08, 2011 12:33 pm
Location: Northern Virginia
Contact:

Re: Outdoor door / gate sensor ?

Post by ryanbuckner »

Here's what it looks like, I had some issues with one of the sensors falling offline. I was able to solve the problem by swapping out the AA batteries that came in the box.
gate-sensor.jpg
gate-sensor.jpg (499.37 KiB) Viewed 461 times
killerdan56
Posts: 16
Joined: Sun Feb 04, 2024 6:27 am

Re: Outdoor door / gate sensor ?

Post by killerdan56 »

Share the script.
ryanbuckner
Posts: 1107
Joined: Sat Oct 08, 2011 12:33 pm
Location: Northern Virginia
Contact:

Re: Outdoor door / gate sensor ?

Post by ryanbuckner »

here's the script:

Code: Select all


import requests
import json
import time

try:
    import indigo
    PRODUCTION = True
except ImportError:
    PRODUCTION = False
    pass

def load_credentials():
    """Load credentials from yolink.json file."""
    global CLIENT_ID, CLIENT_SECRET, LEFT_GATE_ID, LEFT_GATE_TOKEN, RIGHT_GATE_ID, RIGHT_GATE_TOKEN
    with open('/Library/Application Support/Perceptive Automation/Python3-includes/yolink.json', 'r') as file:
        data = json.load(file)
        CLIENT_ID = data['client_id']
        CLIENT_SECRET = data['client_secret']
        LEFT_GATE_ID = data['left_gate_id']
        LEFT_GATE_TOKEN = data['left_gate_token']
        RIGHT_GATE_ID = data['right_gate_id']
        RIGHT_GATE_TOKEN = data['right_gate_token']
        global ACCESS_TOKEN, REFRESH_TOKEN
        ACCESS_TOKEN = data['access_token']
        REFRESH_TOKEN = data['refresh_token']

def save_credentials():
    """Save credentials to yolink.json file."""
    with open('/Library/Application Support/Perceptive Automation/Python3-includes/yolink.json', 'w') as file:
        json.dump({
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'left_gate_id': LEFT_GATE_ID,
            'left_gate_token': LEFT_GATE_TOKEN,
            'right_gate_id': RIGHT_GATE_ID,
            'right_gate_token': RIGHT_GATE_TOKEN,
            'access_token': ACCESS_TOKEN,
            'refresh_token': REFRESH_TOKEN
        }, file)

def get_new_tokens():
    global ACCESS_TOKEN, REFRESH_TOKEN
    response = requests.post(
        'https://api.yosmart.com/open/yolink/token',
        data={
            'grant_type': 'refresh_token',
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'refresh_token': REFRESH_TOKEN
        }
    )
    data = response.json()
    ACCESS_TOKEN = data['access_token']
    REFRESH_TOKEN = data['refresh_token']
    global TOKEN_EXPIRATION_TIME
    TOKEN_EXPIRATION_TIME = time.time() + data['expires_in']  # Set new expiration time
    save_credentials()


# def is_token_expired():
#    return time.time() >= TOKEN_EXPIRATION_TIME

def is_token_expired():
    global ACCESS_TOKEN, REFRESH_TOKEN
    response = requests.post(
        'https://api.yosmart.com/open/yolink/token',
        data={
            'grant_type': 'refresh_token',
            'client_id': CLIENT_ID,
            'client_secret': CLIENT_SECRET,
            'refresh_token': REFRESH_TOKEN
        }
    )
    data = response.json()
    # indigo.server.log(str(data['expires_in']))
    # Check the expires_in value
    expires_in = data.get('expires_in', 0)
    # If expires_in is greater than 0, the token is not expired
    if expires_in > 0:
        return False
    else:
        return True


def get_device_state(device_id, token):
    headers = {
        'Authorization': f'Bearer {ACCESS_TOKEN}',
        'Content-Type': 'application/json'
    }
    data = {
        'method': 'DoorSensor.getState',
        'targetDevice': device_id,
        'token': token
    }
    response = requests.post(
        'https://api.yosmart.com/open/yolink/v2/api',
        headers=headers,
        json=data
    )
    response_data = response.json()
    
    # Check for token-related errors and refresh token if necessary
    if response_data.get('code') in ['000103', '000104', '010104', '010201', '020105', '999999']:
        if response_data['code'] == '010104':  # Token expired
            get_new_tokens()
            headers['Authorization'] = f'Bearer {ACCESS_TOKEN}'  # Update the header with the new token
            response = requests.post(
                'https://api.yosmart.com/open/yolink/v2/api',
                headers=headers,
                json=data
            )
            response_data = response.json()
    
    return response_data


def main():
    global ACCESS_TOKEN, REFRESH_TOKEN, PRODUCTION

    PRODUCTION = True

    # Load credentials
    load_credentials()

    try:
        # Refresh token if necessary
        if is_token_expired():
            get_new_tokens()

        # Get states and battery levels
        left_gate_state = get_device_state(LEFT_GATE_ID, LEFT_GATE_TOKEN)
        right_gate_state = get_device_state(RIGHT_GATE_ID, RIGHT_GATE_TOKEN)

        left_gate_battery = left_gate_state['data']['state']['battery']
        left_gate_status = left_gate_state['data']['state']['state']
        left_gate_online = left_gate_state['data']['online']        

        right_gate_battery = right_gate_state['data']['state']['battery']
        right_gate_status = right_gate_state['data']['state']['state']
        right_gate_online = right_gate_state['data']['online']

        online_status = right_gate_online and left_gate_online

        server_time = indigo.server.getTime()
        formatted_time = server_time.strftime('%m/%d %I:%M%p')

        # Update Indigo variables
        if PRODUCTION:
            indigo.variable.updateValue(514903240, value=right_gate_status)
            indigo.variable.updateValue(246874415, value=left_gate_status)
            indigo.variable.updateValue(1061193685, value=str(online_status).lower())
            indigo.variable.updateValue(410133260, value=formatted_time)
        else:
            print(f"Right Gate: {right_gate_status}")
            print(f"Left Gate: {left_gate_status}")

    except Exception as e:
        print(f"An error occurred: {e}")
        if PRODUCTION:
            indigo.server.log(f"An error occurred: {e}")

if __name__ == "__main__":
    # Define constants
    INDIGO_LEFT_GATE_VAR_ID = 123456789  
    INDIGO_RIGHT_GATE_VAR_ID = 987654321  

    # Initialize token expiration timestamp
    TOKEN_EXPIRATION_TIME = 0
    main()
I have a yolink.json file to hold my API keys

Code: Select all

{
  "client_id": "ua_yourkey",
  "client_secret": "sec_yourkey",
  "left_gate_id": "d88b4c010009e5ac",
  "left_gate_token": "your token",
  "right_gate_id": "your id",
  "right_gate_token": "your token",
  "access_token": "your access toekn",
  "refresh_token": "your refresh token"
}

User avatar
norcoscia
Posts: 1228
Joined: Wed Sep 09, 2015 5:54 am

Re: Outdoor door / gate sensor ?

Post by norcoscia »

Thanks for sharing - mine came in but I have not hooked it up - I’ll post once I do and let folks know how it works8 through HA with flying divers Plug-in.
_______
Norm
Post Reply

Return to “Devices”