Git Product home page Git Product logo

ciao's Introduction

Homebridge

Unlocking Door

Homebridge is a lightweight Node.js server you can run on your home network that emulates the iOS HomeKit API. It supports Plugins, which are community-contributed modules that provide a basic bridge from HomeKit to various 3rd-party APIs provided by manufacturers of "smart home" devices.

Since Siri supports devices added through HomeKit, this means that with Homebridge you can ask Siri to control devices that don't have any support for HomeKit at all. For instance, using just some of the available plugins, you can say:

  • Siri, unlock the back door. [pictured to the right]
  • Siri, open the garage door.
  • Siri, turn on the coffee maker.
  • Siri, turn on the living room lights.
  • Siri, good morning!

You can explore all available plugins at the NPM website by searching for the keyword homebridge-plugin.

Community

The official Homebridge Discord server and Reddit community are where users can discuss Homebridge and ask for help.

Homebridge Discord Homebridge Reddit

HomeKit communities can also be found on both Discord and Reddit.

Installation

raspbian

Raspberry Pi

Official Homebridge Raspberry Pi Image
Install Homebridge on Raspbian


linux

Linux

Debian or Ubuntu Linux | Red Hat, CentOS or Fedora Linux | Arch / Manjaro Linux|Install Homebridge on Arch Linux


macos

macOS

Install Homebridge on macOS


windows

Windows 10 / 11

Install Homebridge on Windows 10 / 11 Using Hyper V


docker

Docker

Install Homebridge on Docker
Synology | Unraid | QNAP | TrueNAS Scale


docker

Synology DSM

Install Homebridge on Synology DSM 7

Other Platforms

Other Platforms

Adding Homebridge to iOS

  1. Open the Home app on your device.
  2. Tap the Home tab, then tap .
  3. Tap Add Accessory, then scan the QR code shown in the Homebridge UI or your Homebridge logs.

If the bridge does not have any accessories yet, you may receive a message saying Additional Set-up Required, this is ok, as you add plugins they will show up in the Home app without the need to pair again (except for Cameras and TVs).

Cameras and most TV devices are exposed as separate accessories and each needs to be paired separately. See this wiki article for instructions.

Interacting with your Devices

Once your device has been added to HomeKit, you should be able to tell Siri to control your devices. However, realize that Siri is a cloud service, and iOS may need some time to synchronize your device information with iCloud.

One final thing to remember is that Siri will almost always prefer its default phrase handling over HomeKit devices. For instance, if you name your Sonos device "Radio" and try saying "Siri, turn on the Radio" then Siri will probably start playing an iTunes Radio station on your phone. Even if you name it "Sonos" and say "Siri, turn on the Sonos", Siri will probably just launch the Sonos app instead. This is why, for instance, the suggested name for the Sonos accessory is "Speakers".

Plugin Development

The https://developers.homebridge.io website contains the Homebridge API reference, available service and characteristic types, and plugin examples.

The Homebridge Plugin Template project provides a base you can use to create your own platform plugin.

There are many existing plugins you can study; you might start with the Homebridge Example Plugins or a plugin that already implements the device type you need.

When writing your plugin, you'll want Homebridge to load it from your development directory instead of publishing it to npm each time. Run this command inside your plugin project folder so your global installation of Homebridge can discover it:

npm link

You can undo this using the npm unlink command.

Then start Homebridge in debug mode:

homebridge -D

This will start up Homebridge and load your in-development plugin. Note that you can also direct Homebridge to load your configuration from somewhere besides the default ~/.homebridge, for example:

homebridge -D -U ~/.homebridge-dev

This is very useful when you are already using your development machine to host a "real" Homebridge instance (with all your accessories) that you don't want to disturb.

Common Issues

Home App Says Accessory Already Added

To fix this, Reset Homebridge.

My iOS App Can't Find Homebridge

Try the following:

  1. Swap between the Bonjour HAP and Ciao mDNS Advertiser options. See the wiki for more details.
  2. iOS DNS cache has gone stale or gotten misconfigured. To fix this, turn airplane mode on and back off to flush the DNS cache.

Limitations

  • One bridge can only expose 150 accessories due to a HomeKit limit. You can however run your plugins as a Child Bridge or run Multiple Homebridge Instances to get around this limitation.
  • Once an accessory has been added to the Home app, changing its name via Homebridge won't be automatically reflected in iOS. You must change it via the Home app as well.

Why Homebridge?

Technically, the device manufacturers should be the ones implementing the HomeKit API. And I'm sure they will - eventually. When they do, this project will be obsolete, and I hope that happens soon. In the meantime, Homebridge is a fun way to get a taste of the future, for those who just can't bear to wait until "real" HomeKit devices are on the market.

Credit

Homebridge was originally created by Nick Farina.

The original HomeKit API work was done by Khaos Tian in his HAP-NodeJS project.

ciao's People

Contributors

bwp91 avatar dependabot[bot] avatar mystk avatar northernman54 avatar oznu avatar sjorge avatar supereg avatar szekelyisz avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

ciao's Issues

Register with a sleep proxy to wake homebridge during MacOS sleep

Describe Your Problem:
Forgive the blue sky noob question. I have homebridge working well on MacOS. Obviously the service is unavailable during MacOS sleep (and I could/should commission a Rpi).

However, as confirmed by _dns-sd -B _sleep-proxy.udp local I have available sleep proxies on the LAN (HomePod, Airport, AppleTV etc). Other services successfully wake MacOS as necessary. Wouldn’t it be cool if MacOS woke when I used HomeKit?

I considered registering the homebridge service with the proxy (dns-sd -R...) but I don’t know the requisite port/service details. I poked around Node.js and homebridge forums and searches but got nobody trying/succeeding to do this.

  • Am I asking the impossible?
  • Anyone considered this?
  • It seems naively straightforward for homebridge to register itself (or I register it) with a sleep proxy...

Best wishes all!

Logs:
n/a

Homebridge Config:
All standard, just a couple of plugins:
homebridge-evohome v0.7.3
homebridge-away-mode v1.5.2

Environment:

  • Node.js Version: v14.15.3
  • NPM Version: 6.14.9
  • Homebridge Version: 1.1.7
  • Operating System: MacOS V11.1 (20C69)
  • Process Supervisor: Systemd / init.d / pm2 / launchctl / Docker / hb-service / other / none

arp output parsing for SunOS/illumos is wrong resulting in only lo0 being used

Analysis

Took me a bit to track down but I noticed ciao wasn't working on illumos, but there was some SunOS handling and given illumos forked from SunOS a few years ago generally we're still rather compatible.

I spend a few hours hunting it down and it fumbles here:

const interfaceName = lines[i].trim().split(NetworkManager.SPACE_PATTERN)[2];

The offset for illumos (and I verified via a friend who has access to an Oracle Solaris 11 box) is wrong, it should be 0.
If I monkey patch the offset from 2 -> 0 in the node_modules generate .js file it works as expected.

Expected Behavior

CIAO should find and use the correct interface(s) instead of just lo0.

Steps To Reproduce

In my case I am using node-red-contrib-homekit-bridged with the advertiser set to CIAO, adding any Service and hitting deploy will trigger it.

Logs

Snippet from the node-red output with DEBUG=ciao:*, you can see it only ever selecting lo0 which is pretty useless.

  ciao:NetworkManager Created NetworkManager with options: {"excludeIpv6Only":true} +4m
  ciao:Responder [amethyst A181._hap._tcp.local.] Going to advertise service... +4m
  ciao:NetworkManager Initial networks [lo0] ignoring [amethyst0] +92ms
  ciao:CiaoService [amethyst A181] Rebuilding service records... +4m
  ciao:Prober Starting to probe for 'amethyst A181._hap._tcp.local.'... +4m
  ciao:Prober Sending prober query number 1 for 'amethyst A181._hap._tcp.local.'... +172ms
  ciao:Prober Sending prober query number 2 for 'amethyst A181._hap._tcp.local.'... +255ms
  ciao:Prober Sending prober query number 3 for 'amethyst A181._hap._tcp.local.'... +252ms
  ciao:Prober Probing for 'amethyst A181._hap._tcp.local.' finished successfully +253ms
  ciao:Announcer [amethyst A181._hap._tcp.local.] Sending announcement for service +4m
  ciao:CiaoService [amethyst A181] Rebuilding service records... +934ms
  ciao:Announcer [amethyst A181._hap._tcp.local.] Sending announcement number 1 +2ms
  ciao:Announcer [amethyst A181._hap._tcp.local.] Sending announcement number 2 +1s
  ciao:Announcer [amethyst A181._hap._tcp.local.] Sending announcement number 3 +2s
  ciao:CiaoService [amethyst A181] Updating txt record... +19s
  ciao:CiaoService [amethyst A181] Rebuilding service records... +1ms
  ciao:Responder [amethyst A181._hap._tcp.local.] Updating 2 record(s) for given service! +20s

Configuration

n/a

Environment

  • OS: OmniOS r151040 (illumos)
  • Software: node-red + node-red-contrib-homekit-bridged
  • Node: v16.14.0
  • npm: 8.3.1

Process Supervisor

not applicable

Additional Context

arp -a -n output from an illumos based distro:

root@amethyst:~# arp -a -n
Net to Media Table: IPv4
Device   IP Address               Mask      Flags      Phys Addr
------ -------------------- --------------- -------- ---------------
amethyst0 10.23.12.1           255.255.255.255          00:25:90:f1:55:06
amethyst0 10.23.10.1           255.255.255.255          00:00:5e:00:01:0a

Output from on an Oracle Solaris system:

af@solaris:~$ arp -an
Net to Media Table: IPv4
Device   IP Address               Mask      Flags      Phys Addr
------ -------------------- --------------- -------- ---------------
net0   172.27.10.254        255.255.255.255          02:08:20:1d:02:93
net0   172.27.10.199        255.255.255.255 SPLA     02:08:20:4b:63:b7

Output for as far as I could tell has not deviated between Oracle Solaris and illumos (both return a uname of SunOS) so that's good knows as fixing one will also fix the other.

I was able to verify this my monkey-patching the offset from 2 to 0 and everything is working (include control of all my devices via home.app)

The debug output now also states that the correct amethyst0 interface is used.

  ciao:NetworkManager Created NetworkManager with options: {"excludeIpv6Only":true} +0ms
  ciao:Responder [amethyst A181._hap._tcp.local.] Going to advertise service... +0ms
  ciao:NetworkManager Initial networks [lo0, amethyst0] ignoring [] +1s
  ciao:CiaoService [amethyst A181] Rebuilding service records... +0ms
  ciao:Prober Starting to probe for 'amethyst A181._hap._tcp.local.'... +0ms
  ciao:Prober Sending prober query number 1 for 'amethyst A181._hap._tcp.local.'... +209ms
  ciao:Prober Sending prober query number 2 for 'amethyst A181._hap._tcp.local.'... +1s
  ciao:Prober Sending prober query number 3 for 'amethyst A181._hap._tcp.local.'... +596ms
  ciao:Prober Probing for 'amethyst A181._hap._tcp.local.' finished successfully +438ms
  ciao:Announcer [amethyst A181._hap._tcp.local.] Sending announcement for service +0ms
  ciao:CiaoService [amethyst A181] Rebuilding service records... +2s
  ciao:Announcer [amethyst A181._hap._tcp.local.] Sending announcement number 1 +26ms
  ciao:CiaoService [amethyst A181] Updating txt record... +712ms
  ciao:CiaoService [amethyst A181] Rebuilding service records... +3ms

I guess a properly fix this getOpenBSD_SUNOS_NetworkInterfaces() would need to be split into a OpenBSd and SunOS variant, or the offset should somehow be toggled between 2 and 0 depending on which one we are. But my typescript knowledge was not sufficient to actually do this and get it to compile :(

homebridge-beta: unhandled exception thrown by Ciao

Testing homebridge-beta. Ciao throws an unhandled exception if you run avahi-browse -at on the same device that is running homebridge.

[2296]: [6/13/2020, 11:00:47 AM] Error: Truncated messages are currently unsupported
[2296]: at Responder.handleQuery (/root/node_modules/homebridge/node_modules/@homebridge/ciao/lib/Responder.js:232:19)
[2296]: at MDNSServer.handleMessage (/root/node_modules/homebridge/node_modules/@homebridge/ciao/lib/MDNSServer.js:243:26)
[2296]: at Socket.emit (events.js:315:20)
[2296]: at UDP.onMessage (dgram.js:908:8)
[2296]: [6/13/2020, 11:00:47 AM] Got SIGTERM, shutting down Homebridge...

-Adrian

ciao Problem with avahi

Describe The Bug:
Iam using openwrt with avahi to Proxy mdns across vlans. With ciao as service in homebridge, homekit cant discover the homebridge (both in same network) after few seconds anymore. Restart avahi, homebridge or WiFi on my client solves the issues for some seconds.. When i switch back to bonjour HAP the issue is solved.

To Reproduce:
Cant Tell you

Expected behavior:
Ciao works with mdns reflector

Logs:

Environment:

  • Node.js Version: 14.16.0
  • NPM Version: 6.14.11
  • Operating System: Debian

Can an mDNS multicast UDP packet be "translated" to multiple unicast UDP packets and re-sent?

Current Situation

I'm dealing with what seems to be a well-known issue, I have services on network A that are advertised via mDNS and I want them to be "seen" by devices on network B. As is well known, mDNS does not propagate to network B, as is by design. There are various solutions to this problem all based on retransmission of the relevant packets within network B (avahi reflection, mdns-repeater, mdns-tunnler to name a few). In most scenarios these solutions work pretty well.

In my particular scenario however, network B is not a "real" network, but rather a group of VPN clients connected to a VPN server running OpenVPN within network A. Trouble is, in this scenario, most VPN implementations (as does OpenVPN) simply discard multicast packets, so even within network B, no services can be advertised between the various clients, let alone service from network A. The only solution is to bridge the network (e.g. via TAP on OpenVPN for example), but this in not available on Apple devices (iOS/Mac OS X etc.).

Doing some more research, it seems the mDNSResponder service on Apple devices binds itself to 0.0.0.0, so in theory one could take the original multicast UDP packets and "convert" them to multiple unicast UDP packets with the same information, then re-send them, thereby overcoming said issue. Looking at Ciao's code it looks like this should be possible and even relatively easy.

I also did in fact confirm via Wireshark that such mDNS messages are received by the target even if sent by unicast UDP and not just when sent by multicast UDP.

Does the above make sense or am I barking up the wrong tree here?

Thanks in advance

Logs

N/A

Configuration

N/A

Environment

  • OS:
  • Software:
  • Node:
  • npm:

Process Supervisor

not applicable

Additional Context

No response

Encountered invalid ipv6 with more than 8 sections!

Describe The Bug:
It seems CIAO is not validating the IPV6 address assigned to the OS and homebridge crashes immediately on start.

Logs:

[Thu Sep 17 2020 09:29:04 GMT-0400 (EDT)] Homebridge is running on port 51826.
[Thu Sep 17 2020 09:29:04 GMT-0400 (EDT)] AssertionError [ERR_ASSERTION]: Encountered invalid ipv6 with more than 8 sections!
    at Object.enlargeIPv6 (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/util/domain-formatter.ts:140:9)
    at AAAARecord.encodeRData (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/coder/records/AAAARecord.ts:33:21)
    at AAAARecord.getRawData (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/coder/ResourceRecord.ts:101:31)
    at rrComparator (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/util/tiebreaking.ts:24:25)
    at Array.sort (<anonymous>)
    at Prober.doTiebreaking (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/responder/Prober.ts:268:62)
    at Prober.handleQuery (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/responder/Prober.ts:243:12)
    at Responder.handleQuery (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/Responder.ts:525:26)
    at MDNSServer.handleMessage (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/MDNSServer.ts:466:20)
    at Socket.emit (events.js:315:20)
[Thu Sep 17 2020 09:29:04 GMT-0400 (EDT)] AssertionError [ERR_ASSERTION]: Encountered invalid ipv6 with more than 8 sections!
    at Object.enlargeIPv6 (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/util/domain-formatter.ts:140:9)
    at AAAARecord.encodeRData (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/coder/records/AAAARecord.ts:33:21)
    at AAAARecord.getRawData (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/coder/ResourceRecord.ts:101:31)
    at rrComparator (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/util/tiebreaking.ts:24:25)
    at Array.sort (<anonymous>)
    at Prober.doTiebreaking (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/responder/Prober.ts:268:62)
    at Prober.handleQuery (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/responder/Prober.ts:243:12)
    at Responder.handleQuery (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/Responder.ts:525:26)
    at MDNSServer.handleMessage (/opt/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/MDNSServer.ts:466:20)
    at Socket.emit (events.js:315:20)
[Thu Sep 17 2020 09:29:04 GMT-0400 (EDT)] Got SIGTERM, shutting down Homebridge...
(node:2801) UnhandledPromiseRejectionWarning: cancelled
(node:2801) UnhandledPromiseRejectionWarning: Unhandled promise rejection. 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(). To terminate the node process on unhandled promise rejection, use the CLI flag `--unhandled-rejections=strict` (see https://nodejs.org/api/cli.html#cli_unhandled_rejections_mode). (rejection id: 2)
(node:2801) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

Homebridge Config:

{
    "bridge": {
        "name": "Home",
        "username": "CC:22:3D:E3:AA:31",
        "port": 51826,
        "pin": "999-01-999"
    },
    "ports": {
        "start": 52100,
        "end": 52150,
        "comment": "This section is used to control the range of ports that separate accessory (like camera or television) should be bind to."
    },
    "accessories": [
        {
            "accessory": "DummySwitch",
            "name": "Home Status",
            "stateful": true
        }
    ],
    "platforms": [
        {
            "name": "Config",
            "port": 9000,
            "auth": "form",
            "theme": "auto",
            "restart": "exec '/opt/etc/init.d/S60homebridge restart'",
            "tempUnits": "f",
            "lang": "auto",
            "sudo": false,
            "log": {
                "method": "custom",
                "command": "/opt/data/homebridge/watch-logs.sh"
            },
            "platform": "config"
        }
    ]
}

Environment:

  • Node.js Version: v12.18.3
  • NPM Version: 6.14.8
  • Homebridge Version: 1.2.2
  • Operating System: other
  • Process Supervisor: other

tvOS 18 ipv4-mapped ipv6 address

Analysis

For some reason getting this error on latest or beta

Expected Behavior

I would expect it to not restart

Steps To Reproduce

install latest Homebridge latest or beta

Logs

AssertionError [ERR_ASSERTION]: ipv4-mapped ipv6 addresses are currently unsupported!
    at enlargeIPv6 (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/util/domain-formatter.ts:137:9)
    at getNetAddress (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/util/domain-formatter.ts:296:26)
    at Function.HAPConnection.getLocalNetworkInterface (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/util/eventedhttp.ts:868:26)
    at new HAPConnection (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/util/eventedhttp.ts:390:43)
    at EventedHTTPServer.onConnection (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/util/eventedhttp.ts:229:24)
    at Server.emit (node:events:519:28)
    at TCP.onconnection (node:net:2204:8)

Configuration

using ciao

Environment

  • OS: macOS 13
  • Software: Homebridge
  • Node: Node 20.14

Process Supervisor

hb-service

Additional Context

No response

Service announcements are not sent over IPv6

Describe the Bug

I am running some devices with IPv4 disabled to test out an IPv6-only environment. This shouldn't be a problem for Bonjour services as they are expected to utilize both IPv4 and IPv6 and therefore make their service announcements or responses using both protocols. This is also the behavior recommended in RFC 6762:

A dual-stack (v4/v6) host can participate in both ".local." zones, and should register its name(s) and perform its lookups both using IPv4 and IPv6. This enables it to reach, and be reached by, both IPv4-only and IPv6-only hosts.

I noticed that my custom HomeKit devices (using HAP-NodeJS with the ciao backend) are not reachable from an IPv6-only client. Turns out that the mDNS announcements and respones are sent only using the IPv4 multicast address. The client (a Mac) therefore can't discover the HomeKit devices and as a result shows them as unresponsive. This is not the case with the official Bonjour implementation. I have no issues discovering my Apple TV or any other Apple device on my network, because they are sending out announcements using both protocols (verified with Wireshark).

I looked at the code and noticed that IPv6 is taken into consideration in a lot of places, but ultimately IPv4 is hardcoded here when sending out anything on the network and in some other places. Same hardcoding applies to binding the listening socket, although netstat shows that ciao is indeed listening to IPv6. I guess the operating system automatically opens a dual stack socket if :: is provided as the listening address?

To reproduce

Disable IPv4 on a client and try to discover a service announced with ciao.

Expected behavior

Services announced using ciao should be discoverable on IPv6-only hosts.

Environment

  • Node.js Version: 14.15.5
  • Yarn Version: 1.22.5
  • Operating System: Raspbian

Node v18.0.0

Analysis

Not able to run with Node v18.0.0

Expected Behavior

load successful

Steps To Reproduce

Install Node 18.0.0 and then restart homebridge

Logs

AssertionError [ERR_ASSERTION]: Could not find valid addresses for interface 'anpi2'
    at NetworkManager.getCurrentNetworkInterfaces (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/NetworkManager.ts:419:13)
    at /usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/NetworkManager.ts:166:12
    at new Promise (<anonymous>)
    at new NetworkManager (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/NetworkManager.ts:165:24)
    at new MDNSServer (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/MDNSServer.ts:193:27)
    at new Responder (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/Responder.ts:129:19)
    at Function.getResponder (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/Responder.ts:121:25)
    at Object.getResponder (/usr/local/lib/node_modules/homebridge/node_modules/@homebridge/ciao/src/index.ts:52:20)
    at new CiaoAdvertiser (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/Advertiser.ts:112:27)
    at Accessory.<anonymous> (/usr/local/lib/node_modules/homebridge/node_modules/hap-nodejs/src/lib/Accessory.ts:1232:26)

Configuration

N/A

Environment

  • OS: macOS 12.4 beta 2
  • Software: Homebridge 1.4.0
  • Node: 18.0.0
  • npm: 8.6.0

Process Supervisor

hb-service

Additional Context

Not a huge issue currently since it is easy to move back with hb-service, but figured I would post this to make people aware.

Homebridge Issue

does not allow multiple services with the same name

Analysis

When the same name is given for multiple service types, the services get renamed with numbers (2), (3), etc.

Expected Behavior

I expect them to all have the same name. This is quite normal as far as I can tell and has been allowed using other libraries.

Steps To Reproduce

Create multiple services with the same and different types.

Logs

NA

Configuration

NA

Environment

  • OS: Mac OS
  • Node: v12

Process Supervisor

not applicable

Additional Context

I'm attempting to use this outside of homebridge

npm update issues unsupported engine warning

Current Situation

performing an npm update command issues unsupported engine warning with CIAO v1.1.6 library

Logs

pi@nodejsdev:~$ npm update
npm WARN EBADENGINE Unsupported engine {
npm WARN EBADENGINE   package: '@homebridge/ciao@1.1.6',
npm WARN EBADENGINE   required: { node: '^14' },
npm WARN EBADENGINE   current: { node: 'v18.16.0', npm: '9.5.1' }
npm WARN EBADENGINE }

Configuration

pi@nodejsdev:~$ npm list
pi@ /home/pi
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
├── [email protected]
└── [email protected]

Environment

  • OS: Linux nodejsdev 5.10.0-21-amd64 #1 SMP Debian 5.10.162-1 (2023-01-21) x86_64 GNU/Linux
  • Software: HAP-NodeJS v0.11.1
  • Node: v18.16.0
  • npm: 9.5.1

Process Supervisor

not applicable

Additional Context

No response

MacOS socket with MDNS group membership added is unable to receive MDNS multicast packets

Analysis

The sockets on MacOS bound by Ciao not able to receive incoming multicast packets despite having addMembership called. Despite this, these sockets are still able to receive the multicast packets sent on the same interface with IP_MULTICAST_LOOP enabled.

This behavior is not exhibited with Linux hosts.

The MacOS system dns-sd command is able to find registered services from Ciao. This means that the only explanation that Avahi stack on a separate Linux host not finding the Ciao registered service is that the the socket.addMembership is silently failing, or that are passing it incorrect parameters on MacOS specifically.

Expected Behavior

Incoming multicast packets should be correctly received by the the multicast sockets bound by MDNS.

Steps To Reproduce

  1. Run the following example code on a MacOS Host
import ciao, { Protocol } from './src';

const responder = ciao.getResponder();

// create a service defining a web server running on port 3000
responder.createService({
    name: 'My Web Server',
    type: 'http',
    port: 3000, // optional, can also be set via updatePort() before advertising
    txt: { // optional
      key: "value",
    }
})

// it must not be advertised, so that a query packet sent by Avahi on another host must be sent to trigger a response packet by Ciao
  1. Run avahi-browse -d local _http._tcp --resolve -t on a separate Linux host.
  2. Expect enp0s31f6 IPv4 My Web Server _http._tcp local to be an entry.

Logs

No logs emitted from Ciao or Avahi.

Configuration

No Configuration.

Environment

MacOS Host: Macmini9,1

  • OS: MacOS 13.1 (Build 22C65)
  • Software: Ciao v1.1.7
  • Node: v20.5.1
  • npm: 9.8.0

Process Supervisor

not applicable

Additional Context

I was developing my own JS MDNS responder when I came across this behavior. I've written an issue about it here:

MatrixAI/js-mdns#29

Advertising a localhost address doesn't seem to work

Analysis

Running this minimal example

import { getResponder } from "@homebridge/ciao";

const responder = getResponder();

const service = responder.createService({
	name: "Example Service",
	type: "http",
	port: 8080,
});


service.advertise().then(() => {
	console.log("Service advertised");
});

does not advertise the service on 127.0.0.1, even though it should. Using restrictedAddresses: [ "127.0.0.1" ] causes the service to not be advertised at all instead. I verified this both with the zeroconfServiceBrowser Screenshot 2023-08-10 015345 and the Bonjour Browser. It correctly advertises on the IPv4 and IPv6 addresses on my Ethernet card, but not on 127.0.0.1.

Expected Behavior

The service be advertised on 127.0.0.1 and ::1 (if IPv6 is not disabled). If restrictedAddresses is used it should still be advertised.

Steps To Reproduce

Just running the minimal example mentioned above is enough.

Logs

Doesn't apply

Configuration

Doesn't apply

Environment

  • OS: Windows 10 Pro 22H2
  • Software: n/a
  • Node: v18.17.1
  • npm: 9.6.7

Process Supervisor

not applicable

Additional Context

I'm not trying to use this library for homebridge, but as a generic mDNS server instead, since it seems to be the only one that supports typescript and is also not dependent on any native code.

arp command don't exist on some distribution

Dears,

arp command (net-tools) don't exists anymore on some distribution, could you check and adapt with ip n ?

2020-09-15T07:05:53.881Z ciao:NetworkManager WARNING Detecting network interfaces for platform 'linux' failed. Trying to assume network interfaces! (Command failed: arp -n -a | grep -v incomplete
/bin/sh: 1: arp: not found
)

Race condition when unpublishing service immediately after advertising

Describe The Bug:
When removing the advertisement for a ciao service immediately after advertising it, it may result in a race condition.
It seems like the Prober isn't properly canceled (or rather started after the service advertisement has already been ended).
Therefore the Prober accesses an already closed MDNSServer.

To Reproduce:

  1. Create a CiaoService service.
  2. Call service.advertise()
  3. Call service.destroy() or service()

Expected behavior:
The Responder should not start a probing step when the service was already unannounced.

Logs:

The reported error is as follows:

Cannot send packets on a closed mdns server!
ERR_SERVER_CLOSED: Cannot send packets on a closed mdns server!
    at MDNSServer.assertBeforeSend (/Users/andi/Documents/WebstormProjects/HAP-NodeJS/node_modules/@homebridge/ciao/src/MDNSServer.ts:403:13)
    at MDNSServer.sendOnAllNetworksForService (/Users/andi/Documents/WebstormProjects/HAP-NodeJS/node_modules/@homebridge/ciao/src/MDNSServer.ts:302:10)
    at MDNSServer.sendQueryBroadcast (/Users/andi/Documents/WebstormProjects/HAP-NodeJS/node_modules/@homebridge/ciao/src/MDNSServer.ts:263:26)
    at Prober.sendProbeRequest (/Users/andi/Documents/WebstormProjects/HAP-NodeJS/node_modules/@homebridge/ciao/src/responder/Prober.ts:165:17)
    at listOnTimeout (node:internal/timers:557:17)
    at processTimers (node:internal/timers:500:7)

Environment:

  • Node.js Version: v17.0.1
  • NPM Version: 8.1.0
  • Ciao Version: 1.1.3
  • Operating System: macOS

Ability to browse for existing services?

Does ciao implements an equivalent of bonjour-hap browsing of services? eg.

bonjour.find({ type: 'http' }, function (service) {
  console.log('Found an HTTP server:', service)
})

Also the docs link in the README is broken.

Open Handles after creating and closing a service

Analysis

When creating a new responder and a new ciao service, not evening advertising it, and thereafter destroying the ciao service again there are still open handles in the system.

// TODO fix: CiaoAdvertiser constructor creates open handles!
// const advertiser = new CiaoAdvertiser(accessoryInfoUnpaired);

advertiser.destroy();

Expected Behavior

There shouldn't be any open handles (e.g. sockets, timeouts, etc). This e.g. stops the process from exiting, specifically noticeable in testing environments.

Steps To Reproduce

In the environment of HAP-NodeJS do the following code steps to reproduce:

const advertiser = new CiaoAdvertiser(accessoryInfoUnpaired);

// ....

advertiser.destroy();

Logs

-

Configuration

-

Environment

  • OS: macOS 13.0.1
  • Software: HAP-NodeJS 0.11.0
  • Node: 19.0.1
  • npm: 8.19.2

Process Supervisor

not applicable

Additional Context

No response

ERROR while installation process

Current Situation

Hello
i tried to install pyatv and got the following problem (see log). I have already asked the team (postlund/pyatv#1907 (comment) pyatv for a solution but they say that it is a problem of zeroconf.
could you help me please?
thanks

Logs

Collecting zeroconf>=0.38.1
Using cached zeroconf-0.47.1.tar.gz (60 kB)
Installing build dependencies ... done
Getting requirements to build wheel ... done
ERROR: Exception:
Traceback (most recent call last):
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/cli/base_command.py", line 160, in exc_logging_wrapper
status = run_func(*args)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/cli/req_command.py", line 247, in wrapper
return func(self, options, args)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/commands/install.py", line 400, in run
requirement_set = resolver.resolve(
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/resolver.py", line 92, in resolve
result = self._result = resolver.resolve(
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 481, in resolve
state = resolution.resolve(requirements, max_rounds=max_rounds)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 373, in resolve
failure_causes = self._attempt_to_pin_criterion(name)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 213, in _attempt_to_pin_criterion
criteria = self._get_updated_criteria(candidate)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 204, in _get_updated_criteria
self._add_to_criteria(criteria, requirement, parent=candidate)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/resolvelib/resolvers.py", line 172, in _add_to_criteria
if not criterion.candidates:
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/resolvelib/structs.py", line 151, in bool
return bool(self._sequence)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 155, in bool
return any(self)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 143, in
return (c for c in iterator if id(c) not in self._incompatible_ids)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/found_candidates.py", line 47, in _iter_built
candidate = func()
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/factory.py", line 206, in _make_candidate_from_link
self._link_candidate_cache[link] = LinkCandidate(
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 297, in init
super().init(
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 162, in init
self.dist = self._prepare()
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 231, in _prepare
dist = self._prepare_distribution()
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/resolution/resolvelib/candidates.py", line 308, in _prepare_distribution
return preparer.prepare_linked_requirement(self._ireq, parallel_builds=True)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 491, in prepare_linked_requirement
return self._prepare_linked_requirement(req, parallel_builds)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 577, in _prepare_linked_requirement
dist = _get_prepared_distribution(
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/operations/prepare.py", line 69, in _get_prepared_distribution
abstract_dist.prepare_distribution_metadata(
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/distributions/sdist.py", line 48, in prepare_distribution_metadata
self._install_build_reqs(finder)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/distributions/sdist.py", line 118, in _install_build_reqs
build_reqs = self._get_build_requires_wheel()
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/distributions/sdist.py", line 95, in _get_build_requires_wheel
return backend.get_requires_for_build_wheel()
File "/opt/homebrew/lib/python3.10/site-packages/pip/_internal/utils/misc.py", line 685, in get_requires_for_build_wheel
return super().get_requires_for_build_wheel(config_settings=cs)
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.py", line 173, in get_requires_for_build_wheel
return self._call_hook('get_requires_for_build_wheel', {
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/pep517/wrappers.py", line 319, in _call_hook
raise BackendUnavailable(data.get('traceback', ''))
pip._vendor.pep517.wrappers.BackendUnavailable: Traceback (most recent call last):
File "/opt/homebrew/lib/python3.10/site-packages/pip/_vendor/pep517/in_process/_in_process.py", line 77, in _build_backend
obj = import_module(mod_path)
File "/opt/homebrew/Cellar/[email protected]/3.10.8/Frameworks/Python.framework/Versions/3.10/lib/python3.10/importlib/init.py", line 126, in import_module
return _bootstrap._gcd_import(name[level:], package, level)
File "", line 1050, in _gcd_import
File "", line 1027, in _find_and_load
File "", line 992, in _find_and_load_unlocked
File "", line 241, in _call_with_frames_removed
File "", line 1050, in _gcd_import
File "", line 1027, in _find_and_load
File "", line 992, in _find_and_load_unlocked
File "", line 241, in _call_with_frames_removed
File "", line 1050, in _gcd_import
File "", line 1027, in _find_and_load
File "", line 992, in _find_and_load_unlocked
File "", line 241, in _call_with_frames_removed
File "", line 1050, in _gcd_import
File "", line 1027, in _find_and_load
File "", line 1004, in _find_and_load_unlocked
ModuleNotFoundError: No module named 'poetry'

Configuration

"bridge": {
        "port": 51421,
        "username": "0E:E9:52:3C:FC:94",
        "name": "Homebridge Mini",
        "pin": "329-01-057",
        "advertiser": "ciao",
        "bind": [
            "en0"
        ]
    },
    "disabledPlugins": [
        "@milo526/homebridge-tuya-web"
    ],
    "platforms": [
        {
            "lang": "de",
            "theme": "cyan",
            "name": "HomeBridgemac",
            "platform": "config",
            "port": 8581,
            "tempUnits": "c",
            "auth": "none"
        },
        {
            "country": "LU",
            "devices": [
                {
                    "ac_fan_control": true,
                    "name": "Klimatisation",
                    "ac_mode": "BOTH",
                    "id": "2268f3eb-5d94-1a49-aefc-xxxxxxxxx",
                    "ac_swing_mode": "BOTH",
                    "type": "AC",
                    "ac_temperature_sensor": true
                }
            ],
            "username": "",
            "thinq1": true,
            "refresh_token": "xxxxxxxxx",
            "platform": "LGThinQ",
            "_bridge": {
                "username": "xxxxxxxx",
                "port": 51921
            },
            "refresh_interval": 60,
            "password": "",
            "language": "de-LU",
            "auth_mode": "token"
        },
        {
            "scenes": false,
            "_bridge": {
                "username": "0xxxxxxxx6",
                "port": 40749
            },
            "name": "TuyaWebPlatform",
            "options": {
                "username": "xxxxxxxxxxx",
                "countryCode": "352",
                "platform": "smart_life",
                "password": "xxxxxxxx"
            },
            "defaults": [
                {
                    "device_type": "dimmer",
                    "id": "bf18029b2xxxxxxxx",
                    "light_characteristics": [
                        "Brightness",
                        "Color",
                        "Color Temperature"
                    ]
                },
                {
                    "device_type": "dimmer",
                    "id": "bf67978eaa51xxxxxxx",
                    "light_characteristics": [
                        "Brightness",
                        "Color",
                        "Color Temperature"
                    ]
                }
            ],
            "platform": "TuyaWebPlatform"
        },
        {
            "_bridge": {
                "port": 58872,
                "username": "0E:74:AE:15:2D:48"
            },
            "platform": "TuyaPlatform",
            "options": {
                "accessKey": "xxxxxxxxx",
                "endpoint": "xxxxxxxxxxxx/",
                "deviceOverrides": [
                    {
                        "schema": [
                            {
                                "type": "Boolean"
                            }
                        ]
                    }
                ],
                "countryCode": 352,
                "accessId": "xxxxxxxxt",
                "projectType": "2",
                "appSchema": "smartlife",
                "username": "xxxxxxxxxxxx",
                "password": "xxxxxxxxxx"
            }
        },
        {
            "whiteEffects": {
                "colorWhiteThreshold": 10,
                "colorWhiteThresholdSimultaniousDevices": 50,
                "colorOffThresholdSimultaniousDevices": 5,
                "simultaniousDevicesColorWhite": true
            },
            "deviceManagement": {
                "blacklistOrWhitelist": "blacklist",
                "blacklistedUniqueIDs": [
                    ""
                ]
            },
            "platform": "homebridge-magichome-dynamic-platform",
            "pruning": {
                "restartsBeforeMissingAccessoriesPruned": 3,
                "pruneAllAccessoriesNextRestart": false,
                "pruneMissingCachedAccessories": false
            },
            "advancedOptions": {
                "logLevel": 3,
                "periodicDiscovery": true,
                "namesWithMacAddress": false
            },
            "_bridge": {
                "username": "0E:BF:C9:A4:B2:C1",
                "port": 48625
            }
        },
        {
            "devices": [
                {
                    "auth": false,
                    "enableDebugMode": false,
                    "infoButtonCommand": "138",
                    "sensorVolume": false,
                    "sensorPower": false,
                    "mqttAuth": false,
                    "disableLogDeviceInfo": false,
                    "port": 80,
                    "enableMqtt": false,
                    "host": "192.168.178.43",
                    "disableLogInfo": false,
                    "mqttDebug": false,
                    "sensorMute": false,
                    "name": "VU+",
                    "volumeControl": 1
                }
            ],
            "platform": "OpenWebIfTv",
            "_bridge": {
                "port": 45341,
                "username": "0E:9A:63:29:28:8D"
            }
        },
        {
            "homepodId": "58:D3:49:xxxxxxxx",
            "serialNumber": "xxxxxxxxxx",
            "httpPort": 7654,
            "verboseModel": false,
            "volumeControl": true,
            "radios": [
                {
                    "name": "Eldoradio",
                    "radioUrl": "https://stream.rtl.lu/live/hls/radio/eldo",
                    "volume": 20,
                    "autoResume": false
                },
                {
                    "name": "Laurent",
                    "radioUrl": "https://youtu.be/6Q7tdD5lJxg",
                    "volume": 61
                },
                {
                    "name": "BBC - Radio 1",
                    "radioUrl": "http://stream.live.vc.bbcmedia.co.uk/bbc_radio_one"
                }
            ],
            "_bridge": {
                "username": "0E:C2:BD:1E:42:BB",
                "port": 30155
            },
            "platform": "HomepodRadioPlatform"
        }
    ],
    "accessories": [
        {
            "accessory": "DummyGarage",
            "_bridge": {
                "username": "A6:DE:8D:6E:6C:89",
                "port": 58818
            },
            "autoCloseDelay": 10,
            "name": "Sesam"
        }
    ]
}

Environment

My system:
-Mac Ventura 13.2
-Homebridge 2.0 beta
-Node : v16.16.0
-npm: 9.4.0
-Homebrew installed (latest version)
-ffmpeg installed (latest version)
-python installed (latest version)

Process Supervisor

hb-service

Additional Context

No response

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.