42 Commits

Author SHA1 Message Date
Darell Tan
bc4c53b5be Fix gitignore to only match top-level dir 2026-01-19 01:34:56 +08:00
Darell Tan
d0a835175e Use VCS version stamp from Go 1.24
Go 1.24 now adds a human readable version to BuildInfo, similar to the
output for `git describe`. Also output version in log on startup.
2026-01-17 01:43:56 +08:00
Darell Tan
aa317d4413 Log microseconds only on dev builds 2026-01-16 19:15:32 +08:00
Darell Tan
c52973f225 Maintain MQTT message order during processing
Previously the message handler spawned a goroutine for each message and
hoped for the best, but obviously it didn't work. Z2M often emitted the
current (old) state first, before sending out the updated state. Without
ordering, the old state might get processed later and overwrote the new,
correct state.

Message handling is now serialized, but decoupled, using a buffered
channel and a separate goroutine for processing.
2026-01-16 18:31:47 +08:00
Darell Tan
8f39074f36 Added receive timestamp for MQTT messages 2026-01-12 23:20:44 +08:00
Darell Tan
93a8d59cd9 Added more debugging output and microsecond log timestamps 2026-01-12 23:17:02 +08:00
Darell Tan
c2da4ca2eb Relax skipped device checks to allow mains-powered dimmers
Technically we should only have skipped the Coordinator because that has
a zero address. Mains dimmers are usually also Routers, not EndDevices.
2026-01-12 22:34:01 +08:00
Darell Tan
7f2c23d426 Upgraded paho.mqtt.golang to v1.5.1 2026-01-12 21:44:12 +08:00
Darell Tan
2cc2cb87fb Fix version string always having "-dirty" suffix 2024-11-25 02:47:49 +08:00
Darell Tan
03004e809f Suppress debug lines for z2m bridge/logging messages 2024-11-25 02:39:32 +08:00
Darell Tan
8fd2666b20 Added gitignore 2024-11-25 02:37:52 +08:00
Darell Tan
f6737b8857 Upgraded hap to v0.0.35 2024-11-24 16:13:53 +08:00
Darell Tan
40302d6ec0 Code cleanup 2024-11-24 16:13:24 +08:00
Darell Tan
9eeab32c8a Added delayed-off for motion sensors
This ensures that the "motion detected" event doesn't flip flop, even if
the motion sensor itself was set to a low timeout like 10-30s. It stays
in the Detected state until no further detections occur within the
timeout period (hardcoded to 1 minute).
2024-11-24 16:03:24 +08:00
Darell Tan
e9b0e4b0f9 Introduce SetCharacteristicValueFunc to the Mapping
This function allows either replacing or modifying the usual
Exposed->Characteristic value propagation.

It also adds a CurrentValue to the mapping to monitor for
changes/updates, regardless of whether the value was updated into the
Characteristic. This will be the source of truth.
2024-11-24 15:52:40 +08:00
Darell Tan
8d5dc24d7d Use Device.Definition.Vendor as the Manufacturer
This makes more sense for white-label devices, since it shows TuYa
instead of _TZnnn_xxxx and Aqara instead of LUMI.
2024-11-24 15:30:02 +08:00
Darell Tan
d4daef7bce Introduce constructors for ExposeMapping
This should allow the ExposeMapping struct to be changed without
constantly impacting its callers.
2024-11-24 15:25:17 +08:00
Darell Tan
b11ab07fbb Update README 2024-11-22 19:20:45 +08:00
Darell Tan
9404fa6161 Add version info to help output 2024-11-22 19:16:13 +08:00
Darell Tan
1922f57a6f Added Z2M description to the Accessory name
This should help you better identify devices if you have added some
description in zigbee2mqtt.
2024-11-22 04:31:06 +08:00
Darell Tan
4d51380873 Don't start HAP server without any devices
This ensures that when iOS reconnects, it doesn't find an empty server
and thinks all the devices have been removed, and removes them all
locally.
2024-11-22 04:01:07 +08:00
Darell Tan
e678f2a31d Only process EndDevices during add and more verbose errors
If a Coordinator is present in the device list, AddDevicesFromJSON will
fail catastrophically, which shouldn't happen. Therefore, make sure only
EndDevices are considered during add. Also updated the tests to check
for this.

Added a device descriptor for failed adds. This will help with
identifying which device failed (and perhaps, why).
2024-11-22 03:40:27 +08:00
Darell Tan
5e24287d8c Reworked translation mapping between Characteristic and Exposed values.
- Broke the code out into its own file.

- Added chaining and flipped translators to assist with re-using
  existing translators.  Also simplified logic when translating between
  HomeKit & Z2M values by removing special cases like the "binary"
  exposes.  Since everything can be expressed with translators &
  translator chains now, the process is streamlined.

- Wired up the defaultTranslator during the setup phase, so when mapping
  is called, there's no nil checks necessary; just a direct call to the
  mapping.Translator.

- Also added more documentation for the translation part since I forgot
  most of it after a year.
2024-11-22 01:27:53 +08:00
Darell Tan
1fbc4d520a Use a more secure PIN config by default
The server used to use the hap default PIN, but using a fixed PIN is not
secure. A random PIN is now generated on first run and displayed to the
console (or journal), similar to how homebridge does it. It can also be
specified explicitly by the user in the config file.
2023-08-12 01:35:07 +08:00
Darell Tan
fe5d0ce14c Disable TCP keepalives explicitly
It looks like Go has adopted 15s TCP keepalives as a default for _all_
TCP connections, which is quite dumb if you ask me.
https://github.com/golang/go/issues/48622

For the HAP server's side, it degrades iOS battery life significantly by
waking the device every 15s to respond to these packets. In the case as
a normal MQTT client, it increases traffic on top of the 60s keepalive
we've already set at the application layer. In both cases, the solution
is to just explicitly disable TCP keepalives.

Upgrade hap to the latest version that contains the fix brutella/hap#36.
2023-08-09 01:41:00 +08:00
Darell Tan
4eac1ba2a9 Fix access check for light expose features
Some dimmers expose features with state|set instead of state|get|set.
Relax the check to cater for more light/dimmers.
2023-08-05 02:17:06 +08:00
Darell Tan
b1949c73fd Handle unknown device types
For devices that we have no idea how to handle, i.e. no services or
expose entries were processed, we return ErrUnknownDeviceType and skip
it during AddDevicesFromJSON(). This prevents a device from showing up
where HomeKit says it's not supported.
2023-08-04 23:49:51 +08:00
Darell Tan
24e3f92a59 Added systemd unit file
The unit file is similar to the one I initially wrote for
regelwerk, which uses DynamicUser to isolate the process.
2023-08-04 01:16:24 +08:00
Darell Tan
8640f0a9c2 Modify default db path 2023-08-04 01:10:35 +08:00
Darell Tan
420313906f Omit log timestamps when running under systemd
The journal will already have timestamps for each logged message.
2023-08-04 00:58:23 +08:00
Darell Tan
ba9a42b64e Added quiet mode for reduced verbosity
This is useful to reduce clutter if you're running the service and it's
writing logs to the main syslog.
2023-08-04 00:56:30 +08:00
Darell Tan
59b049faea Add config options for ListenAddr & Interfaces
These options are helpful when the bridge is running on a multi-homed
device like a wireless router.
2023-08-03 23:28:52 +08:00
Darell Tan
3cfc3f68b0 Added debug mode for more verbose logging
Also had to rename the existing DEBUG consts to DEVMODE, so as to not
confuse the two. DEVMODE is meant for developers and cannot be enabled
on-the-fly, whereas debug mode is for users to check that the bridge is
working, MQTT messages are received etc.

Update logging is throttled to avoid spurious messages for uncoalesced
MQTT updates and motion sensors. On my network with 10 devices, an
update is logged every 1-2 minutes on average.
2023-08-03 21:32:14 +08:00
Darell Tan
54aa0795c3 Fix for unacknowledged numeric Z2M state updates
So far Z2M state updates were only boolean (the device `state` on/off),
but after introducing `brightness` values, Z2M state updates may not be
recognized/acknowledged. Unmarshalled Z2M numeric values are always
float64, but updates sent out via MQTT might not be. As a result, the
values may not directly equal and may never match.

To solve this, cast the outgoing expected value into a float64 to
compare against the received Z2M value, which is already a float64.
2023-06-25 02:34:34 +08:00
Darell Tan
c61da984c9 Add support for dimmers and dimmable bulbs
The exposes entry looks similar to a switch, except the type is a
"light" and it has `state` and `brightness`. Tested only on single
channel dimmers.

Also added a PercentageTranslator to translate between the HomeKit
`brightness`, which is a percentage, to/from an arbitrary numeric value
in Z2M.
2023-06-25 02:20:01 +08:00
Darell Tan
7fbbec79d9 Add support for motion sensors
There doesn't seem to be any distinction in Z2M between occupancy and
motion sensors, but HomeKit has separate types. Most of the sensors are
PIR, so they are technically motion sensors instead of occupancy
sensors. There are of course _real_ occupancy sensors like mmWave, but
we'll deal with those when we get there.
2023-06-16 23:08:09 +08:00
Darell Tan
ca0b667ea1 Z2M JSON exposes.values could be of numeric type
encoding/json would refuse to implicitly cast the numbers into strings.
Currently we don't use these values, so let's preserve their type using
`any` for now.

An example is `keep_time` for occupancy sensors, where it's
[30, 60, 120] seconds.
2023-06-16 22:47:12 +08:00
Darell Tan
48eabc2342 Mark old last_seen devices as "not responding"
Devices that have not received an update since a fixed timeout (24 hrs
for now), based on its last_seen time, will be marked as "not
responding" in the Home app. With this I can identify which devices are
unreachable or dead.

Also needed to upgrade hap with the fix for brutella/hap#30, or the
entire bridge will stop working.
2023-05-22 22:38:20 +08:00
Darell Tan
edade53b06 Record & persist device last_seen time
This will allow us to mark devices as non-responsive if they haven't
been seen in some time.
2023-05-21 02:20:37 +08:00
Darell Tan
e44f33aa29 Don't persist Z2M state with "zero" values
When storing Z2M state, skip properties with default "zero" values. This
should skip devices and properties that were not updated via MQTT yet.
2023-05-14 02:09:17 +08:00
Darell Tan
5c47a410cf Added test for FsStore values clobbering
It was fixed upstream during a rewrite on functions in FsStore.
See my comments on brutella/hap#28.
2023-04-27 02:14:53 +08:00
Darell Tan
84398fc53a "Initial" working version, after cleanup. 2023-04-26 23:20:07 +08:00