Git Product home page Git Product logo

homebridge-flair's Introduction

homebridge-flair

verified-by-homebridge

Flair Smart Vent plug-in for Homebridge using the Flair API.

Installation

  1. Install homebridge using: npm install -g homebridge
  2. Install this plug-in using: npm install -g homebridge-flair
  3. Update your configuration file. See example config.json snippet below.

Configuration

Configuration sample (edit ~/.homebridge/config.json):

{
    "platforms": [
        {
            "clientId": "client_id",
            "clientSecret": "client_secret",
            "username": "user",
            "password": "pass",
            "pollInterval": 60,
            "platform": "Flair",
            "ventAccessoryType": "windowCovering"
        }
    ]
}

Obtaining Credentials

In order to use this plugin you will need to obtain a client id and client secret from Flair.

Start by creating a Flair account at my.flair.co (if you haven't already), then use this web form to request credentials.

More API docs and details

Auto Vs Manual Mode

When you use Pucks with your setup the pucks will appear in the app as a Thermostat.

If you turn those thermostats off it will put the Flair system into Manual mode. If you turn the thermostat to any other setting it will set your system to Flair's Auto mode. As of Version 1.3.0 homekit does not do any switching from Auto to Manual mode. This must be done through the flair app, the Puck thermostats now respect the "off" setting.

Vent Accessory Type

You can specify how vent accessories are shown in HomeKit with the ventAccessoryType property.

windowCovering - Window Covering fan - Fan airPurifier - Air Purifier hidden - Hidden, this is useful if you have a puck in each room and want to only expose the room "thermostats"

Commit format

Commits should be formatted as type(scope): message

The following types are allowed:

Type Description
feat A new feature
fix A bug fix
docs Documentation only changes
style Changes that do not affect the meaning of the code (white-space, formatting,missing semi-colons, etc)
refactor A code change that neither fixes a bug nor adds a feature
perf A code change that improves performance
test Adding missing or correcting existing tests
chore Changes to the build process or auxiliary tools and libraries such as documentation generation

Releasing

A new version is released when a merge or push to main occurs.

We use the rules at default-release-rules.js as our guide to when a series of commits should create a release.

homebridge-flair's People

Contributors

askovi avatar bassrock avatar dependabot[bot] avatar hammerace42 avatar nickv2002 avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

homebridge-flair's Issues

Not installing properly with HOOBS?

I get a successful plugin installation message when installing, But no "Accessories" appear, and log file contains following tow errors ?
6/2/2020, 1:38:26 PM The requested platform "Flair" was not registered by any plugin.
6/2/2020, 1:38:26 PM Your config.json is requesting the platform "Flair" which has not been published by any installed plugins.

I've tried uninstall - reinstall, and rollback to backup - install ... same results each time.

UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "The structure is not available, this should not happen.".

UnhandledPromiseRejection: This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). The promise rejected with the reason "The structure is not available, this should not happen.".

Allow configurable vent accessory type

Currently vent accessories are setup as window coverings (it's unfortunate that HomeKit doesn't have a vent accessory type) and this might not be ideal since:

  1. AFAICT, precise vent position control isn't allowed by Flair. I can only get full open and close position to work through HomeKit, although the Flair app does allow a half open position. This makes the false precision available via the window covering control unnecessary.
  2. Changing vent state is a multi-step process, involving tap + drag to right position, even if just toggling to the full open/full close position.
  3. Users who already have window coverings/shades (I have a bunch) might lose the ability to visually differentiate that accessory from vents (although it's possible to change to a different type of window covering icon, it's still not ideal)

Allowing what accessory the vents show up as to be configurable would give users the option of selecting what accessory works best for them. Here are the accessory types which might be appropriate:

  1. Air Purifier (iconography looks very vent like) - this would be my choice, probably a good default
  2. Fan - this is what I had my vents previously setup as when I was passing it through SmartThings
  3. Window Covering

In all cases, it would be great if the control precision could be setup to match what Flair allows (i.e. 2 speed fan to allow for closed (off), half open (half speed) or open (full speed) or just on/off to match open/closed if setting half open via the Flair API is not possible)

Puck status incorrect

Firstly, thanks for building this plugin. So exciting to not have to pass through SmartThings to get vent controls into HomeKit!

Vent controls and status are working fine, but all pucks show as off status even though the structure is set to cool (manually set - I use a Nest Thermostat and have migrated over to a Google Account so the integration no longer works).

I am seeing the following error in the log:

[5/10/2020, 3:52:05 PM] [Flair] TypeError: Cannot read property 'id' of undefined
    at Client.getStructure (/homebridge/node_modules/homebridge-flair/node_modules/flair-api-ts/src/client/client.ts:216:75)
    at runMicrotasks (<anonymous>)
    at processTicksAndRejections (internal/process/task_queues.js:97:5)
    at FlairPlatform.getNewStructureReadings (/homebridge/node_modules/homebridge-flair/src/platform.ts:88:27)
    at Timeout._onTimeout (/homebridge/node_modules/homebridge-flair/src/platform.ts:56:11)

Homebridge not transferring accessories

Is anyone else not getting their accessories to transfer via Homebridge to HomeKit?
I have my API credentials, username and pw all setup.
Any guidance or assistance would be appreciated!

Action Required: Fix Renovate Configuration

There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.

Error type: Cannot find preset's package (github>Pocket/renovate-config)

The automated release is failing 🚨

🚨 The automated release from the main branch failed. 🚨

I recommend you give this issue a high priority, so other packages depending on you could benefit from your bug fixes and new features.

You can find below the list of errors reported by semantic-release. Each one of them has to be resolved in order to automatically publish your package. I’m sure you can resolve this 💪.

Errors are usually caused by a misconfiguration or an authentication problem. With each error reported below you will find explanation and guidance to help you to resolve it.

Once all the errors are resolved, semantic-release will release your package the next time you push a commit to the main branch. You can also manually restart the failed CI job that runs semantic-release.

If you are not sure how to resolve this, here is some links that can help you:

If those don’t help, or if this issue is reporting something you think isn’t right, you can always ask the humans behind semantic-release.


Invalid npm token.

The npm token configured in the NPM_TOKEN environment variable must be a valid token allowing to publish to the registry https://registry.npmjs.org/.

If you are using Two-Factor Authentication, make configure the auth-only level is supported. semantic-release cannot publish with the default auth-and-writes level.

Please make sure to set the NPM_TOKEN environment variable in your CI with the exact value of the npm token.


Good luck with your project ✨

Your semantic-release bot 📦🚀

'Current Relative Humidity' warning followed by errors after 1.3.4 Homebridge Upgrade

Homebridge v1.3.4
Node v12.14.1
Flair plugin v1.2.7

See logs below ... the issue seems to clutter logs but not have material impact otherwise.

[7/26/2021, 02:48:04] [homebridge-flair] This plugin generated a warning from the characteristic 'Current Relative Humidity': characteristic value expected valid finite number and received "undefined" (undefined). See https://git.io/JtMGR for more info.
[7/26/2021, 02:48:04] [homebridge-flair] Error:
at Characteristic.characteristicWarning (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/Characteristic.ts:2038:105)
at Characteristic.validateUserInput (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/Characteristic.ts:1931:16)
at Characteristic.updateValue (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/Characteristic.ts:1379:20)
at Service.updateCharacteristic (/usr/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/Service.ts:465:35)
at FlairRoomPlatformAccessory.updateRoomReadingsFromRoom (/usr/lib/node_modules/homebridge-flair/src/roomPlatformAccessory.ts:157:10)
at FlairRoomPlatformAccessory.getNewRoomReadings (/usr/lib/node_modules/homebridge-flair/src/roomPlatformAccessory.ts:120:14)
at processTicksAndRejections (internal/process/task_queues.js:94:5)
at Timeout._onTimeout (/usr/lib/node_modules/homebridge-flair/src/roomPlatformAccessory.ts:69:9)
[7/26/2021, 02:48:04] [Flair] Pushed updated current temperature state for Vesper to HomeKit: 22.6112111111111

Request failed status 401 Errors in log file

I am seeing the following error show up regularly in the Homebridge log, but it's unclear if it has an impact on functionality:

[5/11/2020, 6:39:45 AM] [Flair] Error: Request failed with status code 401
    at createError (/homebridge/node_modules/homebridge-flair/node_modules/axios/lib/core/createError.js:16:15)
    at settle (/homebridge/node_modules/homebridge-flair/node_modules/axios/lib/core/settle.js:17:12)
    at IncomingMessage.handleStreamEnd (/homebridge/node_modules/homebridge-flair/node_modules/axios/lib/adapters/http.js:236:11)
    at IncomingMessage.emit (events.js:322:22)
    at IncomingMessage.EventEmitter.emit (domain.js:482:12)
    at endReadableNT (_stream_readable.js:1187:12)
    at processTicksAndRejections (internal/process/task_queues.js:84:21) {
  config: {
    url: '/api/vents/[redacted]/current-reading',
    method: 'get',
    headers: {
      Accept: 'application/json, text/plain, */*',
      Authorization: 'Bearer [redacted]',
      'User-Agent': 'axios/0.19.2'
    },
    baseURL: 'https://api.flair.co',
    transformRequest: [ [Function: transformRequest] ],
    transformResponse: [ [Function: transformResponse] ],
    timeout: 0,
    adapter: [Function: httpAdapter],
    xsrfCookieName: 'XSRF-TOKEN',
    xsrfHeaderName: 'X-XSRF-TOKEN',
    maxContentLength: -1,
    validateStatus: [Function: validateStatus],
    data: undefined
  },
  request: ClientRequest {
    _events: [Object: null prototype] {
      socket: [Function],
      error: [Array],
      abort: [Function],
      aborted: [Function],
      timeout: [Function],
      prefinish: [Function: requestOnPrefinish]
    },
    _eventsCount: 6,
    _maxListeners: undefined,
    outputData: [],
    outputSize: 0,
    writable: true,
    _last: true,
    chunkedEncoding: false,
    shouldKeepAlive: false,
    useChunkedEncodingByDefault: false,
    sendDate: false,
    _removedConnection: false,
    _removedContLen: false,
    _removedTE: false,
    _contentLength: 0,
    _hasBody: true,
    _trailer: '',
    finished: true,
    _headerSent: true,
    socket: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      _SNICallback: null,
      servername: 'api.flair.co',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.flair.co',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 5658416,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    connection: TLSSocket {
      _tlsOptions: [Object],
      _secureEstablished: true,
      _securePending: false,
      _newSessionPending: false,
      _controlReleased: true,
      _SNICallback: null,
      servername: 'api.flair.co',
      alpnProtocol: false,
      authorized: true,
      authorizationError: null,
      encrypted: true,
      _events: [Object: null prototype],
      _eventsCount: 10,
      connecting: false,
      _hadError: false,
      _parent: null,
      _host: 'api.flair.co',
      _readableState: [ReadableState],
      readable: true,
      _maxListeners: undefined,
      _writableState: [WritableState],
      writable: false,
      allowHalfOpen: false,
      _sockname: null,
      _pendingData: null,
      _pendingEncoding: '',
      server: undefined,
      _server: null,
      ssl: [TLSWrap],
      _requestCert: true,
      _rejectUnauthorized: true,
      parser: null,
      _httpMessage: [Circular],
      [Symbol(res)]: [TLSWrap],
      [Symbol(asyncId)]: 5658416,
      [Symbol(kHandle)]: [TLSWrap],
      [Symbol(kSetNoDelay)]: false,
      [Symbol(lastWriteQueueSize)]: 0,
      [Symbol(timeout)]: null,
      [Symbol(kBuffer)]: null,
      [Symbol(kBufferCb)]: null,
      [Symbol(kBufferGen)]: null,
      [Symbol(kCapture)]: false,
      [Symbol(kBytesRead)]: 0,
      [Symbol(kBytesWritten)]: 0,
      [Symbol(connect-options)]: [Object]
    },
    _header: 'GET /api/vents/[redacted]/current-reading HTTP/1.1\r\n' +
      'Accept: application/json, text/plain, */*\r\n' +
      'Authorization: Bearer [Redacted]\r\n' +
      'User-Agent: axios/0.19.2\r\n' +
      'Host: api.flair.co\r\n' +
      'Connection: close\r\n' +
      '\r\n',
    _onPendingData: [Function: noopPendingOutput],
    agent: Agent {
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      defaultPort: 443,
      protocol: 'https:',
      options: [Object],
      requests: {},
      sockets: [Object],
      freeSockets: {},
      keepAliveMsecs: 1000,
      keepAlive: false,
      maxSockets: Infinity,
      maxFreeSockets: 256,
      maxCachedSessions: 100,
      _sessionCache: [Object],
      [Symbol(kCapture)]: false
    },
    socketPath: undefined,
    method: 'GET',
    insecureHTTPParser: undefined,
    path: '/api/vents/[redacted]/current-reading',
    _ended: true,
    res: IncomingMessage {
      _readableState: [ReadableState],
      readable: false,
      _events: [Object: null prototype],
      _eventsCount: 3,
      _maxListeners: undefined,
      socket: [TLSSocket],
      connection: [TLSSocket],
      httpVersionMajor: 1,
      httpVersionMinor: 1,
      httpVersion: '1.1',
      complete: true,
      headers: [Object],
      rawHeaders: [Array],
      trailers: {},
      rawTrailers: [],
      aborted: false,
      upgrade: false,
      url: '',
      method: null,
      statusCode: 401,
      statusMessage: 'UNAUTHORIZED',
      client: [TLSSocket],
      _consuming: false,
      _dumped: false,
      req: [Circular],
      responseUrl: 'https://api.flair.co/api/vents/[redacted]/current-reading',
      redirects: [],
      [Symbol(kCapture)]: false
    },
    aborted: false,
    timeoutCb: null,
    upgradeOrConnect: false,
    parser: null,
    maxHeadersCount: null,
    reusedSocket: false,
    _redirectable: Writable {
      _writableState: [WritableState],
      writable: true,
      _events: [Object: null prototype],
      _eventsCount: 2,
      _maxListeners: undefined,
      _options: [Object],
      _redirectCount: 0,
      _redirects: [],
      _requestBodyLength: 0,
      _requestBodyBuffers: [],
      _onNativeResponse: [Function],
      _currentRequest: [Circular],
      _currentUrl: 'https://api.flair.co/api/vents/[redacted]/current-reading',
      [Symbol(kCapture)]: false
    },
    [Symbol(kCapture)]: false,
    [Symbol(kNeedDrain)]: false,
    [Symbol(corked)]: 0,
    [Symbol(kOutHeaders)]: [Object: null prototype] {
      accept: [Array],
      authorization: [Array],
      'user-agent': [Array],
      host: [Array]
    }
  },
  response: {
    status: 401,
    statusText: 'UNAUTHORIZED',
    headers: {
      date: 'Mon, 11 May 2020 13:39:45 GMT',
      'content-type': 'application/json; charset=utf-8',
      'content-length': '112',
      connection: 'close',
      server: 'gunicorn/20.0.4',
      'access-control-allow-origin': 'None',
      'access-control-max-age': '21600',
      'access-control-allow-headers': 'authorization, content-type, accept, x-admin-mode, user-agent',
      'access-control-allow-credentials': 'true'
    },
    config: {
      url: '/api/vents/[redacted]/current-reading',
      method: 'get',
      headers: [Object],
      baseURL: 'https://api.flair.co',
      transformRequest: [Array],
      transformResponse: [Array],
      timeout: 0,
      adapter: [Function: httpAdapter],
      xsrfCookieName: 'XSRF-TOKEN',
      xsrfHeaderName: 'X-XSRF-TOKEN',
      maxContentLength: -1,
      validateStatus: [Function: validateStatus],
      data: undefined
    },
    request: ClientRequest {
      _events: [Object: null prototype],
      _eventsCount: 6,
      _maxListeners: undefined,
      outputData: [],
      outputSize: 0,
      writable: true,
      _last: true,
      chunkedEncoding: false,
      shouldKeepAlive: false,
      useChunkedEncodingByDefault: false,
      sendDate: false,
      _removedConnection: false,
      _removedContLen: false,
      _removedTE: false,
      _contentLength: 0,
      _hasBody: true,
      _trailer: '',
      finished: true,
      _headerSent: true,
      socket: [TLSSocket],
      connection: [TLSSocket],
      _header: 'GET /api/vents/[redacted]/current-reading HTTP/1.1\r\n' +
        'Accept: application/json, text/plain, */*\r\n' +
        'Authorization: Bearer [redacted]\r\n' +
        'User-Agent: axios/0.19.2\r\n' +
        'Host: api.flair.co\r\n' +
        'Connection: close\r\n' +
        '\r\n',
      _onPendingData: [Function: noopPendingOutput],
      agent: [Agent],
      socketPath: undefined,
      method: 'GET',
      insecureHTTPParser: undefined,
      path: '/api/vents/[redacted]/current-reading',
      _ended: true,
      res: [IncomingMessage],
      aborted: false,
      timeoutCb: null,
      upgradeOrConnect: false,
      parser: null,
      maxHeadersCount: null,
      reusedSocket: false,
      _redirectable: [Writable],
      [Symbol(kCapture)]: false,
      [Symbol(kNeedDrain)]: false,
      [Symbol(corked)]: 0,
      [Symbol(kOutHeaders)]: [Object: null prototype]
    },
    data: { errors: [Array] }
  },
  isAxiosError: true,
  toJSON: [Function]
}

Read-Only Flair Sensors

Thanks for the work you've done on this plugin! It works really well.

Feature enhancement Request

I would like to expose all the Flair temperatures as read-only sensors instead of adjustable thermostats. (This is mostly because of the way HomeKit interacts with Siri, if there are multiple thermostats I have to tell Siri which one I meant, and I never want to actually adjust the Flair one).

Would it be possible to have an alternate mode where the Flair pucks are presented as non-adjustable sensors instead?

Thanks again!

Error 500 after HB 1.1.1 upgrade

I upgraded HB to v1.1.1 which appears to have upgraded the node version and potentially deprecated and API ...

Afterwards logs are filled with the following errors .... FYI, I replaced what appeared as keys with "[REDACTED]"

[7/27/2020, 20:57:31] [Flair] Error: Request failed with status code 500
at createError (/usr/lib/node_modules/homebridge-flair/node_modules/axios/lib/core/createError.js:16:15)
at settle (/usr/lib/node_modules/homebridge-flair/node_modules/axios/lib/core/settle.js:17:12)
at IncomingMessage.handleStreamEnd (/usr/lib/node_modules/homebridge-flair/node_modules/axios/lib/adapters/http.js:236:11)
at IncomingMessage.emit (events.js:228:7)
at endReadableNT (_stream_readable.js:1185:12)
at processTicksAndRejections (internal/process/task_queues.js:81:21) {
config: {
url: '/api/vents/[REDACTED]/current-reading',
method: 'get',
headers: {
Accept: 'application/json, text/plain, /',
Authorization: 'Bearer [REDACTED],
'User-Agent': 'axios/0.19.2'
},
baseURL: 'https://api.flair.co',
transformRequest: [ [Function: transformRequest] ],
transformResponse: [ [Function: transformResponse] ],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: ClientRequest {
_events: [Object: null prototype] {
socket: [Function],
abort: [Function],
aborted: [Function],
error: [Function],
timeout: [Function],
prefinish: [Function: requestOnPrefinish]
},
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.flair.co',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.flair.co',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 8294,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
connection: TLSSocket {
_tlsOptions: [Object],
_secureEstablished: true,
_securePending: false,
_newSessionPending: false,
_controlReleased: true,
_SNICallback: null,
servername: 'api.flair.co',
alpnProtocol: false,
authorized: true,
authorizationError: null,
encrypted: true,
_events: [Object: null prototype],
_eventsCount: 9,
connecting: false,
_hadError: false,
_parent: null,
_host: 'api.flair.co',
_readableState: [ReadableState],
readable: true,
_maxListeners: undefined,
_writableState: [WritableState],
writable: false,
allowHalfOpen: false,
_sockname: null,
_pendingData: null,
_pendingEncoding: '',
server: undefined,
_server: null,
ssl: [TLSWrap],
_requestCert: true,
_rejectUnauthorized: true,
parser: null,
_httpMessage: [Circular],
[Symbol(res)]: [TLSWrap],
[Symbol(asyncId)]: 8294,
[Symbol(kHandle)]: [TLSWrap],
[Symbol(lastWriteQueueSize)]: 0,
[Symbol(timeout)]: null,
[Symbol(kBuffer)]: null,
[Symbol(kBufferCb)]: null,
[Symbol(kBufferGen)]: null,
[Symbol(kBytesRead)]: 0,
[Symbol(kBytesWritten)]: 0,
[Symbol(connect-options)]: [Object]
},
_header: 'GET /api/vents/[REDACTED]/current-reading HTTP/1.1\r\n' +
'Accept: application/json, text/plain, /\r\n' +
'Authorization: Bearer [REDACTED] +
'User-Agent: axios/0.19.2\r\n' +
'Host: api.flair.co\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: Agent {
_events: [Object: null prototype],
_eventsCount: 1,
_maxListeners: undefined,
defaultPort: 443,
protocol: 'https:',
options: [Object],
requests: {},
sockets: [Object],
freeSockets: {},
keepAliveMsecs: 1000,
keepAlive: false,
maxSockets: Infinity,
maxFreeSockets: 256,
maxCachedSessions: 100,
_sessionCache: [Object]
},
socketPath: undefined,
method: 'GET',
path: '/api/vents/[REDACTED]/current-reading',
_ended: true,
res: IncomingMessage {
_readableState: [ReadableState],
readable: false,
_events: [Object: null prototype],
_eventsCount: 3,
_maxListeners: undefined,
socket: [TLSSocket],
connection: [TLSSocket],
httpVersionMajor: 1,
httpVersionMinor: 1,
httpVersion: '1.1',
complete: true,
headers: [Object],
rawHeaders: [Array],
trailers: {},
rawTrailers: [],
aborted: false,
upgrade: false,
url: '',
method: null,
statusCode: 500,
statusMessage: 'Internal Server Error',
client: [TLSSocket],
_consuming: false,
_dumped: false,
req: [Circular],
responseUrl: 'https://api.flair.co/api/vents/[REDACTED]/current-reading',
redirects: []
},
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: Writable {
_writableState: [WritableState],
writable: true,
_events: [Object: null prototype],
_eventsCount: 2,
_maxListeners: undefined,
_options: [Object],
_redirectCount: 0,
_redirects: [],
_requestBodyLength: 0,
_requestBodyBuffers: [],
_onNativeResponse: [Function],
_currentRequest: [Circular],
_currentUrl: 'https://api.flair.co/api/vents/[REDACTED]/current-reading'
},
[Symbol(kNeedDrain)]: false,
[Symbol(isCorked)]: false,
[Symbol(kOutHeaders)]: [Object: null prototype] {
accept: [Array],
authorization: [Array],
'user-agent': [Array],
host: [Array]
}
},
response: {
status: 500,
statusText: 'Internal Server Error',
headers: {
date: 'Mon, 27 Jul 2020 19:57:31 GMT',
'content-type': 'text/html',
'content-length': '141',
connection: 'close'
},
config: {
url: '/api/vents/[REDACTED]/current-reading',
method: 'get',
headers: [Object],
baseURL: 'https://api.flair.co',
transformRequest: [Array],
transformResponse: [Array],
timeout: 0,
adapter: [Function: httpAdapter],
xsrfCookieName: 'XSRF-TOKEN',
xsrfHeaderName: 'X-XSRF-TOKEN',
maxContentLength: -1,
validateStatus: [Function: validateStatus],
data: undefined
},
request: ClientRequest {
_events: [Object: null prototype],
_eventsCount: 6,
_maxListeners: undefined,
outputData: [],
outputSize: 0,
writable: true,
_last: true,
chunkedEncoding: false,
shouldKeepAlive: false,
useChunkedEncodingByDefault: false,
sendDate: false,
_removedConnection: false,
_removedContLen: false,
_removedTE: false,
_contentLength: 0,
_hasBody: true,
_trailer: '',
finished: true,
_headerSent: true,
socket: [TLSSocket],
connection: [TLSSocket],
_header: 'GET /api/vents/[REDACTED]/current-reading HTTP/1.1\r\n' +
'Accept: application/json, text/plain, /\r\n' +
'Authorization: Bearer [REDACTED] +
'User-Agent: axios/0.19.2\r\n' +
'Host: api.flair.co\r\n' +
'Connection: close\r\n' +
'\r\n',
_onPendingData: [Function: noopPendingOutput],
agent: [Agent],
socketPath: undefined,
method: 'GET',
path: '/api/vents/[REDACTED]/current-reading',
_ended: true,
res: [IncomingMessage],
aborted: false,
timeoutCb: null,
upgradeOrConnect: false,
parser: null,
maxHeadersCount: null,
_redirectable: [Writable],
[Symbol(kNeedDrain)]: false,
[Symbol(isCorked)]: false,
[Symbol(kOutHeaders)]: [Object: null prototype]
},
data: '\n' +
' \n' +
' <title>Internal Server Error</title>\n' +
' \n' +
' \n' +
'

Internal Server Error

\n' +
' \n' +
' \n' +
'\n'
},
isAxiosError: true,
toJSON: [Function]
}
[7/27/2020, 20:57:32] [Flair] Pushed updated current temperature state for Master-18ad to HomeKit: 23.53

Dependency Dashboard

This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.

Pending Approval

These branches will be created by Renovate only once you click their checkbox below.

  • chore(deps): update github-actions to v3 (major) (actions/checkout, actions/setup-node)

Pending Status Checks

These updates await pending status checks. To force their creation now, click the checkbox below.

  • chore(deps): update typescript-eslint monorepo to v5.48.0 (@typescript-eslint/eslint-plugin, @typescript-eslint/parser)

Detected dependencies

github-actions
.github/workflows/linter.yml
  • actions/checkout v2@dc323e67f16fb5f7663d20ff7941f27f5809e9b6
  • actions/setup-node v2.5.1@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
  • ghcr.io/github/super-linter slim-v4@sha256:900277f36d47d5ddc460d901ea9dfcb1d348f7390066f800a0895cd88866b31f
.github/workflows/publish.yml
  • actions/checkout v2@dc323e67f16fb5f7663d20ff7941f27f5809e9b6
  • actions/setup-node v2@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
  • cycjimmy/semantic-release-action v2
.github/workflows/test.yml
  • actions/checkout v2@dc323e67f16fb5f7663d20ff7941f27f5809e9b6
  • actions/setup-node v2@1f8c6b94b26d0feae1e387ca63ccbdc44d27b561
npm
package.json
  • class-transformer ^0.5.1
  • flair-api-ts ^1.0.28
  • reflect-metadata ^0.1.13
  • @semantic-release/changelog 6.0.2
  • @semantic-release/commit-analyzer 9.0.2
  • @semantic-release/git 10.0.1
  • @semantic-release/github 8.0.7
  • @semantic-release/npm 9.0.1
  • @semantic-release/release-notes-generator 10.0.3
  • @types/node 18.11.18
  • @typescript-eslint/eslint-plugin 5.47.1
  • @typescript-eslint/parser 5.47.1
  • eslint 8.31.0
  • homebridge 1.6.0
  • nodemon 2.0.20
  • rimraf 3.0.2
  • ts-node 10.9.1
  • typescript 4.9.4
  • node >=10.17.0

  • Check this box to trigger a request for Renovate to run again on this repository

How do I resolve: Error getting structure readings this is usually incorrect credentials, ensure you entered the right credentials.

Hi, I'm using Hoobs, and I've entered my client id, secret, username, and password from Flair in my plugin configuration. It keeps throwing the same error:

Flair Bridge starting
12/17/2022, 11:45:02 AMFlair BridgeLoaded plugin 'homebridge-flair'
12/17/2022, 11:45:02 AMFlair BridgeLoading 1 platforms...
12/17/2022, 11:45:03 AMFlair BridgeBridge is running on port 51836.
12/17/2022, 11:45:03 AMFlair BridgeFlairERRORError getting structure readings this is usually incorrect credentials, ensure you entered the right credentials.

I'm fairly certain I have the correct credentials. Thoughts on what I might be doing wrong or how to troubleshoot further?

Thanks in advance!

Consolidate Puck sensors and controls into single accessory

I think the Homekit UI would be cleaner if the humidity and temperature sensor readings from the Puck were consolidated with the thermostat control. I have a lot Homekit accessories, so am always looking to keep the UI in the HomeKit app as clear as possible.

Controlling Flair vents locally

Hi, could it be possible to control the Flair vents locally (open/close)? Last week, Flair's API went down, and all the vents were stuck in their current state. I had no way to open or close the vents myself until the API came back online.

Users of Homeassistant reported that their Flair plugin allowed them to control the open/closed state of the vents locally while the Flair API was down, saving them from having to unscrew the vents from the ceiling just to let air flow through!

I was wondering if those of us using homebridge might be able to do the same thing?

Many thanks!

"Cannot read properties of null" resulting in accessories not responding

I just started running into this recently - I'd had the plugin running without problems for several weeks, and then the accessories would randomly start showing as "not responding" in the Home app. This would coincide with seeing this error in the Homebridge log:

/homebridge/node_modules/homebridge-flair/node_modules/follow-redirects/index.js:592
  const dot = subdomain.length - domain.length - 1;
                                        ^
TypeError: Cannot read properties of null (reading 'length')
    at isSubdomain (/homebridge/node_modules/homebridge-flair/node_modules/follow-redirects/index.js:592:41)
    at RedirectableRequest._processResponse (/homebridge/node_modules/homebridge-flair/node_modules/follow-redirects/index.js:427:7)
    at ClientRequest.RedirectableRequest._onNativeResponse (/homebridge/node_modules/homebridge-flair/node_modules/follow-redirects/index.js:57:10)
    at Object.onceWrapper (node:events:628:26)
    at ClientRequest.emit (node:events:513:28)
    at HTTPParser.parserOnIncomingClient [as onIncoming] (node:_http_client:693:27)
    at HTTPParser.parserOnHeadersComplete (node:_http_common:117:17)
    at Socket.socketOnData (node:_http_client:534:22)
    at Socket.emit (node:events:513:28)
    at addChunk (node:internal/streams/readable:324:12)
[11/28/2022, 9:04:58 AM] [homebridge-flair] Child bridge process ended
[11/28/2022, 9:04:58 AM] [homebridge-flair] Process Ended. Code: 1, Signal: null
[11/28/2022, 9:05:05 AM] [homebridge-flair] Restarting Process...
[11/28/2022, 9:05:06 AM] [homebridge-flair] Launched child bridge with PID 37421
[11/28/2022, 9:05:06 AM] Registering platform 'homebridge-flair.Flair'
[11/28/2022, 9:05:06 AM] [homebridge-flair] Loaded homebridge-flair v1.3.5 child bridge successfully
[11/28/2022, 9:05:06 AM] Loaded 8 cached accessories from cachedAccessories.0ED7C5442EB6.
[11/28/2022, 9:05:06 AM] Homebridge v1.6.0 (HAP v0.11.0) (homebridge-flair) is running on port 31970.

The only thing that I've been able to figure out that allows the accessories to work again once this happens is to completely remove the them from Homekit and re-add them, which is not ideal since it seems to be a fairly regular thing now - re-adding only seems to work for around 24 hours.

Other things I've tried that do not work:

  • Restarting just the Flair bridge
  • Restarting Homebridge entirely
  • Resetting the API credentials (set to incorrect creds -> restart -> set back to correct creds -> restart)
  • Resetting the Flair credentials (set to incorrect creds -> restart -> set back to correct creds -> restart)

This "smells" like an authentication issue - perhaps the plugin is caching an access token that's recently started expiring after 24h? That's why I'd tried switching the credentials around, but maybe what I did wasn't enough to remove whatever is cached.

Accessory is out of compliance

trying to add the bridge to HomeKit is giving the out of compliance error
IMG_4737

all the accessories are present (and can be interacted with) within homebridge web. But connection to HomeKit is broken

Error: Cannot find module 'moment'

I get this error when I load up or restart my homebridge server:

====================
[12/9/2023, 11:38:35 AM] ERROR LOADING PLUGIN homebridge-flair:
[12/9/2023, 11:38:35 AM] Error: Cannot find module 'moment'
Require stack:

  • /usr/local/lib/node_modules/homebridge-flair/node_modules/flair-api-ts/dist/client.js
  • /usr/local/lib/node_modules/homebridge-flair/node_modules/flair-api-ts/dist/index.js
  • /usr/local/lib/node_modules/homebridge-flair/dist/roomPlatformAccessory.js
  • /usr/local/lib/node_modules/homebridge-flair/dist/platform.js
  • /usr/local/lib/node_modules/homebridge-flair/dist/index.js
  • /usr/local/lib/node_modules/homebridge/lib/plugin.js
  • /usr/local/lib/node_modules/homebridge/lib/pluginManager.js
  • /usr/local/lib/node_modules/homebridge/lib/server.js
  • /usr/local/lib/node_modules/homebridge/lib/cli.js
  • /usr/local/lib/node_modules/homebridge/bin/homebridge
    at Function.Module._resolveFilename (node:internal/modules/cjs/loader:995:15)
    at Function.Module._load (node:internal/modules/cjs/loader:841:27)
    at Module.require (node:internal/modules/cjs/loader:1061:19)
    at require (node:internal/modules/cjs/helpers:103:18)
    at Object. (/client.ts:3:1)
    at Module._compile (node:internal/modules/cjs/loader:1159:14)
    at Object.Module._extensions..js (node:internal/modules/cjs/loader:1213:10)
    at Module.load (node:internal/modules/cjs/loader:1037:32)
    at Function.Module._load (node:internal/modules/cjs/loader:878:12)
    at Module.require (node:internal/modules/cjs/loader:1061:19)

if I npm -v moment, I get:
8.19.2

Any ideas what can fix this issue?

Recurring error when using Ecobee Smart Sensor

The Ecobee Smart Sensor unlike the puck doesn't provide humidity measurement, the homebridge-flair keeps logging the error below every minutes. Perhaps there is a way to identify that it is not a puck, otherwise I would suggest that the driver logs these events 5 times, and states that it will no longer report it, otherwise as it clutters the logs unnecessarily.

"Flair BridgeError[Flair Bridge C556@Entrée Solaire@@current Relative Humidity] characteristic value expected valid finite number and received "undefined" (undefined)"

Thanks for this driver.

Provide a zone thermostat for Flair Mode settings

I thought changing to Auto mode would set the mode to Auto. However, it appears to change the apparent mode on the HomeKit thermostat display, but does nothing.

Since the Flair system has a system set point and system mode control, would it be possible to create a virtual system thermostat with the system set point and system mode (Heat/Cool/Auto/Off) to duplicate the Flair system function?

BTW, thank you for the work you have done!

Logic for auto

} else if(value === this.platform.Characteristic.TargetHeatingCoolingState.AUTO) {
this.platform.setStructureMode(FlairMode.AUTO, StructureHeatCoolMode.COOL).then((structure: Structure) => {
callback(null, this.platform.Characteristic.TargetHeatingCoolingState.AUTO);
this.updateFromStructure(structure);
});

Why do you override the "auto" setting by setting "cool" for the structure on these lines above (and in getCurrentHeatingCoolingStateFromStructure)?

This seems like a bug to me? In the Home app you choose "auto" which sets the state in the Flair app to "cool".

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.