├── .gitignore ├── .travis.yml ├── CREDITS ├── LICENSE ├── README.md ├── _example ├── client.go ├── example │ └── main.go └── tv │ └── main.go ├── _img └── home-icon.png ├── accessory ├── README.md ├── accessory.go ├── bridge.go ├── camera.go ├── colored_lightbulb.go ├── constant.go ├── container.go ├── container_test.go ├── doc.go ├── lightbulb.go ├── outlet.go ├── switch.go ├── television.go ├── thermometer.go ├── thermostat.go └── window.go ├── characteristic ├── accessory_flags.go ├── accessory_identifier.go ├── active.go ├── active_identifier.go ├── administrator_only_access.go ├── air_particulate_density.go ├── air_particulate_size.go ├── air_quality.go ├── app_matching_identifier.go ├── audio_feedback.go ├── battery_level.go ├── bool.go ├── bool_test.go ├── brightness.go ├── bytes.go ├── bytes_test.go ├── carbon_dioxide_detected.go ├── carbon_dioxide_level.go ├── carbon_dioxide_peak_level.go ├── carbon_monoxide_detected.go ├── carbon_monoxide_level.go ├── carbon_monoxide_peak_level.go ├── category.go ├── characteristic.go ├── characteristic_test.go ├── charging_state.go ├── closed_captions.go ├── color_temperature.go ├── configure_bridged_accessory.go ├── configure_bridged_accessory_status.go ├── configured_name.go ├── constants.go ├── contact_sensor_state.go ├── cooling_threshold_temperature.go ├── current_air_purifier_state.go ├── current_ambient_light_level.go ├── current_door_state.go ├── current_fan_state.go ├── current_heater_cooler_state.go ├── current_heating_cooling_state.go ├── current_horizontal_tilt_angle.go ├── current_humidifier_dehumidifier_state.go ├── current_media_state.go ├── current_position.go ├── current_relative_humidity.go ├── current_slat_state.go ├── current_temperature.go ├── current_tilt_angle.go ├── current_time.go ├── current_transport.go ├── current_vertical_tilt_angle.go ├── current_visibility_state.go ├── day_of_the_week.go ├── digital_zoom.go ├── discover_bridged_accessories.go ├── discovered_bridged_accessories.go ├── display_order.go ├── doc.go ├── filter_change_indication.go ├── filter_life_level.go ├── firmware_revision.go ├── float.go ├── float_test.go ├── hardware_revision.go ├── heating_cooling_mode_test.go ├── heating_threshold_temperature.go ├── hold_position.go ├── hue.go ├── identifier.go ├── identify.go ├── identify_test.go ├── image_mirroring.go ├── image_rotation.go ├── in_use.go ├── input_device_type.go ├── input_source_type.go ├── int.go ├── int_test.go ├── is_configured.go ├── leak_detected.go ├── link_quality.go ├── lock_control_point.go ├── lock_current_state.go ├── lock_last_known_action.go ├── lock_management_auto_security_timeout.go ├── lock_physical_controls.go ├── lock_target_state.go ├── logs.go ├── manufacturer.go ├── manufacturer_test.go ├── model.go ├── model_test.go ├── motion_detected.go ├── mute.go ├── name.go ├── name_test.go ├── night_vision.go ├── nitrogen_dioxide_density.go ├── obstruction_detected.go ├── occupancy_detected.go ├── on.go ├── on_test.go ├── optical_zoom.go ├── outlet_in_use.go ├── ozone_density.go ├── pair_setup.go ├── pair_verify.go ├── pairing_features.go ├── pairing_pairings.go ├── picture_mode.go ├── pm10_density.go ├── pm2_5_density.go ├── position_state.go ├── power_mode_selection.go ├── program_mode.go ├── programmable_switch_event.go ├── programmable_switch_output_state.go ├── reachable.go ├── relative_humidity_dehumidifier_threshold.go ├── relative_humidity_humidifier_threshold.go ├── remaining_duration.go ├── remote_key.go ├── reset_filter_indication.go ├── rotation_direction.go ├── rotation_speed.go ├── saturation.go ├── security_system_alarm_type.go ├── security_system_current_state.go ├── security_system_target_state.go ├── selected_camera_recording_configuration.go ├── selected_rtp_stream_configuration.go ├── selected_stream_configuration.go ├── serial_number.go ├── service_label_index.go ├── service_label_namespace.go ├── set_duration.go ├── setup_endpoints.go ├── slat_type.go ├── sleep_discovery_mode.go ├── smoke_detected.go ├── software_revision.go ├── status_active.go ├── status_fault.go ├── status_jammed.go ├── status_low_battery.go ├── status_tampered.go ├── streaming_status.go ├── string.go ├── string_test.go ├── sulphur_dioxide_density.go ├── supported_audio_recording_configuration.go ├── supported_audio_stream_configuration.go ├── supported_camera_recording_configuration.go ├── supported_rtp_configuration.go ├── supported_video_recording_configuration.go ├── supported_video_stream_configuration.go ├── swing_mode.go ├── target_air_purifier_state.go ├── target_air_quality.go ├── target_door_state.go ├── target_fan_state.go ├── target_heater_cooler_state.go ├── target_heating_cooling_state.go ├── target_horizontal_tilt_angle.go ├── target_humidifier_dehumidifier_state.go ├── target_media_state.go ├── target_position.go ├── target_relative_humidity.go ├── target_slat_state.go ├── target_temperature.go ├── target_tilt_angle.go ├── target_vertical_tilt_angle.go ├── target_visibility_state.go ├── temperature_display_units.go ├── test_conn.go ├── time_update.go ├── tunnel_connection_timeout.go ├── tunneled_accessory_advertising.go ├── tunneled_accessory_connected.go ├── tunneled_accessory_state_number.go ├── valve_type.go ├── version.go ├── voc_density.go ├── volume.go ├── volume_control_type.go ├── volume_selector.go ├── water_level.go ├── wifi_capabilities.go └── wifi_configuration_control.go ├── cmd ├── import.go ├── markdown.go └── swift_decl.go ├── config.go ├── config_test.go ├── crypto ├── chacha20poly1305 │ └── chacha20_poly1305.go ├── cryptographer.go ├── curve25519 │ └── curve25519.go ├── doc.go ├── ed25519.go ├── hkdf │ └── hkdf.go ├── packet.go ├── packet_test.go ├── secure_session.go └── secure_session_test.go ├── db ├── database.go ├── database_test.go ├── doc.go └── entity.go ├── doc.go ├── event ├── constant.go ├── event_emitter.go ├── event_emitter_test.go └── event_listener.go ├── gen ├── golang │ ├── category.go │ ├── characteristic.go │ ├── path.go │ └── service.go ├── markdown │ ├── category.go │ └── service.go ├── metadata.go ├── metadata.json └── swift │ ├── characteristic.go │ ├── enum.go │ └── service.go ├── go.mod ├── go.sum ├── hap ├── chunked_writer.go ├── chunked_writer_test.go ├── connection.go ├── constants.go ├── context.go ├── data │ ├── characteristics.go │ ├── characteristics_test.go │ └── doc.go ├── device.go ├── device_test.go ├── doc.go ├── endpoint │ ├── doc.go │ ├── pair-setup.go │ ├── pair-verify.go │ ├── pairings.go │ └── resource.go ├── handler.go ├── http │ ├── accessories.go │ ├── characteristics.go │ ├── doc.go │ ├── err.go │ ├── identify.go │ ├── json.go │ ├── listener.go │ └── server.go ├── keep_alive.go ├── notification.go ├── notification_test.go ├── pair │ ├── admin.go │ ├── doc.go │ ├── error_types.go │ ├── errors.go │ ├── handler.go │ ├── method_types.go │ ├── pairing_controller.go │ ├── pairing_controller_test.go │ ├── sequence_types.go │ ├── setup_client_controller.go │ ├── setup_client_session.go │ ├── setup_controller_test.go │ ├── setup_server_controller.go │ ├── setup_server_session.go │ ├── srp.go │ ├── tag_types.go │ ├── verify_client_controller.go │ ├── verify_controller_test.go │ ├── verify_server_controller.go │ └── verify_session.go ├── secured_device.go └── session.go ├── ip_transport.go ├── log └── log.go ├── password.go ├── password_test.go ├── rtp ├── audio_stream_configuration.go ├── configuration.go ├── setup_endpoints.go ├── setup_endpoints_test.go ├── stream_configuration.go ├── stream_configuration_test.go ├── stream_controller_test.go ├── stream_status.go └── video_stream_configuration.go ├── service ├── README.md ├── accessory_information.go ├── air_purifier.go ├── air_quality_sensor.go ├── battery_service.go ├── bridge_configuration.go ├── bridging_state.go ├── camera_control.go ├── camera_recording_management.go ├── camera_rtp_stream_management.go ├── carbon_dioxide_sensor.go ├── carbon_monoxide_sensor.go ├── colored_lightbulb.go ├── constants.go ├── contact_sensor.go ├── cooler.go ├── doc.go ├── door.go ├── doorbell.go ├── fan.go ├── fan_v2.go ├── faucet.go ├── filter_maintenance.go ├── garage_door_opener.go ├── heater.go ├── heater_cooler.go ├── humidifier_dehumidifier.go ├── humidity_sensor.go ├── input_source.go ├── irrigation_system.go ├── leak_sensor.go ├── light_sensor.go ├── lightbulb.go ├── lock_management.go ├── lock_mechanism.go ├── microphone.go ├── motion_sensor.go ├── occupancy_sensor.go ├── outlet.go ├── security_system.go ├── service.go ├── service_label.go ├── service_test.go ├── slat.go ├── smoke_sensor.go ├── speaker.go ├── stateful_programmable_switch.go ├── stateless_programmable_switch.go ├── switch.go ├── television.go ├── temperature_sensor.go ├── thermostat.go ├── time_information.go ├── tunneled_btle_accessory_service.go ├── valve.go ├── wifitransport.go ├── window.go └── window_covering.go ├── termination.go ├── tlv8 ├── decoder.go ├── encoder.go ├── marshal.go ├── marshal_test.go ├── reader.go ├── unmarshal.go ├── unmarshal_test.go ├── writer.go └── writer_test.go ├── transport.go └── util ├── container.go ├── doc.go ├── file_storage.go ├── file_storage_test.go ├── mac.go ├── rand.go ├── rand_test.go ├── serial.go ├── serial_test.go ├── storage.go ├── string.go ├── tlv8.go ├── tlv8_test.go ├── xhmurl.go └── xhmurl_test.go /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /data 3 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | sudo: false 2 | language: go 3 | go: 4 | - 1.13.x 5 | - master 6 | os: 7 | - linux 8 | - osx 9 | dist: trusty 10 | install: true -------------------------------------------------------------------------------- /_example/example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/brutella/hc" 5 | "github.com/brutella/hc/accessory" 6 | "github.com/brutella/hc/log" 7 | 8 | "time" 9 | ) 10 | 11 | func main() { 12 | log.Debug.Enable() 13 | switchInfo := accessory.Info{ 14 | Name: "Lamp", 15 | } 16 | acc := accessory.NewSwitch(switchInfo) 17 | 18 | config := hc.Config{Pin: "12344321", Port: "12345", StoragePath: "./db"} 19 | t, err := hc.NewIPTransport(config, acc.Accessory) 20 | 21 | if err != nil { 22 | log.Info.Panic(err) 23 | } 24 | 25 | // Log to console when client (e.g. iOS app) changes the value of the on characteristic 26 | acc.Switch.On.OnValueRemoteUpdate(func(on bool) { 27 | if on == true { 28 | log.Debug.Println("Client changed switch to on") 29 | } else { 30 | log.Debug.Println("Client changed switch to off") 31 | } 32 | }) 33 | 34 | // Periodically toggle the switch's on characteristic 35 | go func() { 36 | for { 37 | on := !acc.Switch.On.GetValue() 38 | if on == true { 39 | log.Debug.Println("Switch is on") 40 | } else { 41 | log.Debug.Println("Switch is off") 42 | } 43 | acc.Switch.On.SetValue(on) 44 | time.Sleep(5 * time.Second) 45 | } 46 | }() 47 | 48 | hc.OnTermination(func() { 49 | <-t.Stop() 50 | }) 51 | 52 | t.Start() 53 | } 54 | -------------------------------------------------------------------------------- /_img/home-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/brutella/hc/dfb7ee9aad34263b2703e5734bc1521efe7dfa9b/_img/home-icon.png -------------------------------------------------------------------------------- /accessory/README.md: -------------------------------------------------------------------------------- 1 | | Accessory | Category | 2 | | --- | --- | 3 | | Unknown | 0 | 4 | | Other | 1 | 5 | | Bridge | 2 | 6 | | Fan | 3 | 7 | | Garage Door Opener | 4 | 8 | | Lightbulb | 5 | 9 | | Door Lock | 6 | 10 | | Outlet | 7 | 11 | | Switch | 8 | 12 | | Thermostat | 9 | 13 | | Sensor | 10 | 14 | | Security System | 11 | 15 | | Door | 12 | 16 | | Window | 13 | 17 | | Window Covering | 14 | 18 | | Programmable Switch | 15 | 19 | | IP Camera | 17 | 20 | | Video Doorbell | 18 | 21 | | Air Purifier | 19 | 22 | | Heater | 20 | 23 | | Air Conditioner | 21 | 24 | | Humidifier | 22 | 25 | | Dehumidifier | 23 | 26 | | Sprinklers | 28 | 27 | | Faucets | 29 | 28 | | Shower Systems | 30 | 29 | | Television | 31 | 30 | | Remote Control | 32 | -------------------------------------------------------------------------------- /accessory/bridge.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | type Bridge struct { 4 | *Accessory 5 | } 6 | 7 | // NewBridge returns a bridge which implements model.Bridge. 8 | func NewBridge(info Info) *Bridge { 9 | acc := Bridge{} 10 | acc.Accessory = New(info, TypeBridge) 11 | 12 | return &acc 13 | } 14 | -------------------------------------------------------------------------------- /accessory/camera.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | // Camera provides RTP video streaming. 8 | type Camera struct { 9 | *Accessory 10 | Control *service.CameraControl 11 | StreamManagement1 *service.CameraRTPStreamManagement 12 | StreamManagement2 *service.CameraRTPStreamManagement 13 | } 14 | 15 | // NewCamera returns an IP camera accessory. 16 | func NewCamera(info Info) *Camera { 17 | acc := Camera{} 18 | acc.Accessory = New(info, TypeIPCamera) 19 | acc.Control = service.NewCameraControl() 20 | acc.AddService(acc.Control.Service) 21 | 22 | // TODO (mah) a camera must support at least 2 rtp streams 23 | acc.StreamManagement1 = service.NewCameraRTPStreamManagement() 24 | acc.StreamManagement2 = service.NewCameraRTPStreamManagement() 25 | acc.AddService(acc.StreamManagement1.Service) 26 | // acc.AddService(acc.StreamManagement2.Service) 27 | 28 | return &acc 29 | } 30 | -------------------------------------------------------------------------------- /accessory/colored_lightbulb.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type ColoredLightbulb struct { 8 | *Accessory 9 | Lightbulb *service.ColoredLightbulb 10 | } 11 | 12 | // NewLightbulb returns an light bulb accessory which one light bulb service. 13 | func NewColoredLightbulb(info Info) *ColoredLightbulb { 14 | acc := ColoredLightbulb{} 15 | acc.Accessory = New(info, TypeLightbulb) 16 | acc.Lightbulb = service.NewColoredLightbulb() 17 | 18 | acc.Lightbulb.Brightness.SetValue(100) 19 | 20 | acc.AddService(acc.Lightbulb.Service) 21 | 22 | return &acc 23 | } 24 | -------------------------------------------------------------------------------- /accessory/doc.go: -------------------------------------------------------------------------------- 1 | // Package accessory implements the HomeKit accessories. 2 | package accessory 3 | -------------------------------------------------------------------------------- /accessory/lightbulb.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Lightbulb struct { 8 | *Accessory 9 | Lightbulb *service.Lightbulb 10 | } 11 | 12 | // NewLightbulb returns an light bulb accessory which one light bulb service. 13 | func NewLightbulb(info Info) *Lightbulb { 14 | acc := Lightbulb{} 15 | acc.Accessory = New(info, TypeLightbulb) 16 | acc.Lightbulb = service.NewLightbulb() 17 | 18 | acc.AddService(acc.Lightbulb.Service) 19 | 20 | return &acc 21 | } 22 | -------------------------------------------------------------------------------- /accessory/outlet.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Outlet struct { 8 | *Accessory 9 | Outlet *service.Outlet 10 | } 11 | 12 | // NewOutlet returns an outlet accessory containing one outlet service. 13 | func NewOutlet(info Info) *Outlet { 14 | acc := Outlet{} 15 | acc.Accessory = New(info, TypeOutlet) 16 | acc.Outlet = service.NewOutlet() 17 | acc.Outlet.OutletInUse.SetValue(true) 18 | 19 | acc.AddService(acc.Outlet.Service) 20 | 21 | return &acc 22 | } 23 | -------------------------------------------------------------------------------- /accessory/switch.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Switch struct { 8 | *Accessory 9 | Switch *service.Switch 10 | } 11 | 12 | // NewSwitch returns a switch which implements model.Switch. 13 | func NewSwitch(info Info) *Switch { 14 | acc := Switch{} 15 | acc.Accessory = New(info, TypeSwitch) 16 | acc.Switch = service.NewSwitch() 17 | acc.AddService(acc.Switch.Service) 18 | 19 | return &acc 20 | } 21 | -------------------------------------------------------------------------------- /accessory/television.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Television struct { 8 | *Accessory 9 | Television *service.Television 10 | Speaker *service.Speaker 11 | } 12 | 13 | // NewTelevision returns a television accessory. 14 | func NewTelevision(info Info) *Television { 15 | acc := Television{} 16 | acc.Accessory = New(info, TypeTelevision) 17 | acc.Television = service.NewTelevision() 18 | acc.Speaker = service.NewSpeaker() 19 | 20 | acc.AddService(acc.Television.Service) 21 | acc.AddService(acc.Speaker.Service) 22 | 23 | return &acc 24 | } 25 | -------------------------------------------------------------------------------- /accessory/thermometer.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Thermometer struct { 8 | *Accessory 9 | 10 | TempSensor *service.TemperatureSensor 11 | } 12 | 13 | // NewTemperatureSensor returns a Thermometer which implements model.Thermometer. 14 | func NewTemperatureSensor(info Info, temp, min, max, steps float64) *Thermometer { 15 | acc := Thermometer{} 16 | acc.Accessory = New(info, TypeThermostat) 17 | acc.TempSensor = service.NewTemperatureSensor() 18 | acc.TempSensor.CurrentTemperature.SetValue(temp) 19 | acc.TempSensor.CurrentTemperature.SetMinValue(min) 20 | acc.TempSensor.CurrentTemperature.SetMaxValue(max) 21 | acc.TempSensor.CurrentTemperature.SetStepValue(steps) 22 | 23 | acc.AddService(acc.TempSensor.Service) 24 | 25 | return &acc 26 | } 27 | -------------------------------------------------------------------------------- /accessory/thermostat.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Thermostat struct { 8 | *Accessory 9 | 10 | Thermostat *service.Thermostat 11 | } 12 | 13 | // NewThermostat returns a Thermostat which implements model.Thermostat. 14 | func NewThermostat(info Info, temp, min, max, steps float64) *Thermostat { 15 | acc := Thermostat{} 16 | acc.Accessory = New(info, TypeThermostat) 17 | acc.Thermostat = service.NewThermostat() 18 | acc.Thermostat.CurrentTemperature.SetValue(temp) 19 | acc.Thermostat.CurrentTemperature.SetMinValue(min) 20 | acc.Thermostat.CurrentTemperature.SetMaxValue(max) 21 | acc.Thermostat.CurrentTemperature.SetStepValue(steps) 22 | 23 | acc.Thermostat.TargetTemperature.SetValue(temp) 24 | acc.Thermostat.TargetTemperature.SetMinValue(min) 25 | acc.Thermostat.TargetTemperature.SetMaxValue(max) 26 | acc.Thermostat.TargetTemperature.SetStepValue(steps) 27 | 28 | acc.AddService(acc.Thermostat.Service) 29 | 30 | return &acc 31 | } 32 | -------------------------------------------------------------------------------- /accessory/window.go: -------------------------------------------------------------------------------- 1 | package accessory 2 | 3 | import ( 4 | "github.com/brutella/hc/service" 5 | ) 6 | 7 | type Windows struct { 8 | *Accessory 9 | Window *service.Window 10 | } 11 | 12 | // NewWindow returns a window which implements model.NewWindow. 13 | func NewWindow(info Info, currentState int) *Windows { 14 | acc := Windows{} 15 | acc.Accessory = New(info, TypeWindow) 16 | acc.Window = service.NewWindow() 17 | acc.Window.CurrentPosition.SetValue(currentState) 18 | acc.AddService(acc.Window.Service) 19 | 20 | return &acc 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/accessory_flags.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeAccessoryFlags = "A6" 5 | 6 | type AccessoryFlags struct { 7 | *Int 8 | } 9 | 10 | func NewAccessoryFlags() *AccessoryFlags { 11 | char := NewInt(TypeAccessoryFlags) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(0) 16 | 17 | return &AccessoryFlags{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/accessory_identifier.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeAccessoryIdentifier = "57" 5 | 6 | type AccessoryIdentifier struct { 7 | *String 8 | } 9 | 10 | func NewAccessoryIdentifier() *AccessoryIdentifier { 11 | char := NewString(TypeAccessoryIdentifier) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &AccessoryIdentifier{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/active.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ActiveInactive int = 0 6 | ActiveActive int = 1 7 | ) 8 | 9 | const TypeActive = "B0" 10 | 11 | type Active struct { 12 | *Int 13 | } 14 | 15 | func NewActive() *Active { 16 | char := NewInt(TypeActive) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &Active{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/active_identifier.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeActiveIdentifier = "E7" 5 | 6 | type ActiveIdentifier struct { 7 | *Int 8 | } 9 | 10 | func NewActiveIdentifier() *ActiveIdentifier { 11 | char := NewInt(TypeActiveIdentifier) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | 16 | char.SetValue(0) 17 | 18 | return &ActiveIdentifier{char} 19 | } 20 | -------------------------------------------------------------------------------- /characteristic/administrator_only_access.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeAdministratorOnlyAccess = "1" 5 | 6 | type AdministratorOnlyAccess struct { 7 | *Bool 8 | } 9 | 10 | func NewAdministratorOnlyAccess() *AdministratorOnlyAccess { 11 | char := NewBool(TypeAdministratorOnlyAccess) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &AdministratorOnlyAccess{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/air_particulate_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeAirParticulateDensity = "64" 5 | 6 | type AirParticulateDensity struct { 7 | *Float 8 | } 9 | 10 | func NewAirParticulateDensity() *AirParticulateDensity { 11 | char := NewFloat(TypeAirParticulateDensity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &AirParticulateDensity{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/air_particulate_size.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | AirParticulateSize2_5Μm int = 0 6 | AirParticulateSize10Μm int = 1 7 | ) 8 | 9 | const TypeAirParticulateSize = "65" 10 | 11 | type AirParticulateSize struct { 12 | *Int 13 | } 14 | 15 | func NewAirParticulateSize() *AirParticulateSize { 16 | char := NewInt(TypeAirParticulateSize) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &AirParticulateSize{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/air_quality.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | AirQualityUnknown int = 0 6 | AirQualityExcellent int = 1 7 | AirQualityGood int = 2 8 | AirQualityFair int = 3 9 | AirQualityInferior int = 4 10 | AirQualityPoor int = 5 11 | ) 12 | 13 | const TypeAirQuality = "95" 14 | 15 | type AirQuality struct { 16 | *Int 17 | } 18 | 19 | func NewAirQuality() *AirQuality { 20 | char := NewInt(TypeAirQuality) 21 | char.Format = FormatUInt8 22 | char.Perms = []string{PermRead, PermEvents} 23 | 24 | char.SetValue(0) 25 | 26 | return &AirQuality{char} 27 | } 28 | -------------------------------------------------------------------------------- /characteristic/app_matching_identifier.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeAppMatchingIdentifier = "A4" 5 | 6 | type AppMatchingIdentifier struct { 7 | *Bytes 8 | } 9 | 10 | func NewAppMatchingIdentifier() *AppMatchingIdentifier { 11 | char := NewBytes(TypeAppMatchingIdentifier) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &AppMatchingIdentifier{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/audio_feedback.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeAudioFeedback = "5" 5 | 6 | type AudioFeedback struct { 7 | *Bool 8 | } 9 | 10 | func NewAudioFeedback() *AudioFeedback { 11 | char := NewBool(TypeAudioFeedback) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &AudioFeedback{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/battery_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeBatteryLevel = "68" 5 | 6 | type BatteryLevel struct { 7 | *Int 8 | } 9 | 10 | func NewBatteryLevel() *BatteryLevel { 11 | char := NewInt(TypeBatteryLevel) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &BatteryLevel{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/bool.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type Bool struct { 8 | *Characteristic 9 | } 10 | 11 | func NewBool(typ string) *Bool { 12 | number := NewCharacteristic(typ) 13 | number.Format = FormatBool 14 | 15 | return &Bool{number} 16 | } 17 | 18 | // SetValue sets a value 19 | func (c *Bool) SetValue(value bool) { 20 | c.UpdateValue(value) 21 | } 22 | 23 | // GetValue returns the value as bool 24 | func (c *Bool) GetValue() bool { 25 | return c.Characteristic.GetValue().(bool) 26 | } 27 | 28 | // OnValueRemoteGet calls fn when the value was read by a client. 29 | func (c *Bool) OnValueRemoteGet(fn func() bool) { 30 | c.OnValueGet(func() interface{} { 31 | return fn() 32 | }) 33 | } 34 | 35 | // OnValueRemoteUpdate calls fn when the value was updated by a client. 36 | func (c *Bool) OnValueRemoteUpdate(fn func(bool)) { 37 | c.OnValueUpdateFromConn(func(conn net.Conn, c *Characteristic, new, old interface{}) { 38 | fn(new.(bool)) 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /characteristic/bool_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestBool(t *testing.T) { 8 | b := NewOn() 9 | b.Value = true 10 | 11 | if is, want := b.GetValue(), true; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | 15 | b.SetValue(false) 16 | 17 | if is, want := b.GetValue(), false; is != want { 18 | t.Fatalf("is=%v want=%v", is, want) 19 | } 20 | } 21 | 22 | func TestValueUpdate(t *testing.T) { 23 | b := NewOn() 24 | 25 | var newValue bool 26 | b.OnValueRemoteUpdate(func(value bool) { 27 | newValue = value 28 | }) 29 | 30 | b.UpdateValueFromConnection(true, TestConn) 31 | 32 | if is, want := b.GetValue(), true; is != want { 33 | t.Fatalf("is=%v want=%v", is, want) 34 | } 35 | 36 | if is, want := newValue, true; is != want { 37 | t.Fatalf("is=%v want=%v", is, want) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /characteristic/brightness.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeBrightness = "8" 5 | 6 | type Brightness struct { 7 | *Int 8 | } 9 | 10 | func NewBrightness() *Brightness { 11 | char := NewInt(TypeBrightness) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &Brightness{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/bytes.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "encoding/base64" 5 | "net" 6 | ) 7 | 8 | type Bytes struct { 9 | *String 10 | } 11 | 12 | func NewBytes(typ string) *Bytes { 13 | s := NewString(typ) 14 | s.Format = FormatTLV8 15 | 16 | return &Bytes{s} 17 | } 18 | 19 | func (bs *Bytes) SetValue(b []byte) { 20 | bs.String.SetValue(base64FromBytes(b)) 21 | } 22 | 23 | func (bs *Bytes) GetValue() []byte { 24 | str := bs.String.GetValue() 25 | if b, err := base64.StdEncoding.DecodeString(str); err != nil { 26 | return []byte{} 27 | } else { 28 | return b 29 | } 30 | } 31 | 32 | func (bs *Bytes) OnValueRemoteUpdate(fn func([]byte)) { 33 | bs.OnValueUpdateFromConn(func(conn net.Conn, c *Characteristic, new, old interface{}) { 34 | str := new.(string) 35 | if b, err := base64.StdEncoding.DecodeString(str); err != nil { 36 | fn([]byte{}) 37 | } else { 38 | fn(b) 39 | } 40 | }) 41 | } 42 | 43 | func base64FromBytes(b []byte) string { 44 | return base64.StdEncoding.EncodeToString(b) 45 | } 46 | -------------------------------------------------------------------------------- /characteristic/bytes_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "encoding/base64" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestBytesEncoding(t *testing.T) { 10 | val := []byte{0xFA, 0xAA} 11 | b := NewBytes(TypeLogs) 12 | b.Perms = PermsAll() 13 | b.SetValue(val) 14 | 15 | expect := base64.StdEncoding.EncodeToString(val) 16 | 17 | if x := b.Value; reflect.DeepEqual(x, expect) == false { 18 | t.Fatal(x) 19 | } 20 | 21 | if x := b.GetValue(); reflect.DeepEqual(x, val) == false { 22 | t.Fatal(x) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/carbon_dioxide_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CarbonDioxideDetectedCO2LevelsNormal int = 0 6 | CarbonDioxideDetectedCO2LevelsAbnormal int = 1 7 | ) 8 | 9 | const TypeCarbonDioxideDetected = "92" 10 | 11 | type CarbonDioxideDetected struct { 12 | *Int 13 | } 14 | 15 | func NewCarbonDioxideDetected() *CarbonDioxideDetected { 16 | char := NewInt(TypeCarbonDioxideDetected) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &CarbonDioxideDetected{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/carbon_dioxide_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCarbonDioxideLevel = "93" 5 | 6 | type CarbonDioxideLevel struct { 7 | *Float 8 | } 9 | 10 | func NewCarbonDioxideLevel() *CarbonDioxideLevel { 11 | char := NewFloat(TypeCarbonDioxideLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100000) 16 | 17 | char.SetValue(0) 18 | 19 | return &CarbonDioxideLevel{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/carbon_dioxide_peak_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCarbonDioxidePeakLevel = "94" 5 | 6 | type CarbonDioxidePeakLevel struct { 7 | *Float 8 | } 9 | 10 | func NewCarbonDioxidePeakLevel() *CarbonDioxidePeakLevel { 11 | char := NewFloat(TypeCarbonDioxidePeakLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100000) 16 | 17 | char.SetValue(0) 18 | 19 | return &CarbonDioxidePeakLevel{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/carbon_monoxide_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CarbonMonoxideDetectedCOLevelsNormal int = 0 6 | CarbonMonoxideDetectedCOLevelsAbnormal int = 1 7 | ) 8 | 9 | const TypeCarbonMonoxideDetected = "69" 10 | 11 | type CarbonMonoxideDetected struct { 12 | *Int 13 | } 14 | 15 | func NewCarbonMonoxideDetected() *CarbonMonoxideDetected { 16 | char := NewInt(TypeCarbonMonoxideDetected) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &CarbonMonoxideDetected{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/carbon_monoxide_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCarbonMonoxideLevel = "90" 5 | 6 | type CarbonMonoxideLevel struct { 7 | *Float 8 | } 9 | 10 | func NewCarbonMonoxideLevel() *CarbonMonoxideLevel { 11 | char := NewFloat(TypeCarbonMonoxideLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | 17 | char.SetValue(0) 18 | 19 | return &CarbonMonoxideLevel{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/carbon_monoxide_peak_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCarbonMonoxidePeakLevel = "91" 5 | 6 | type CarbonMonoxidePeakLevel struct { 7 | *Float 8 | } 9 | 10 | func NewCarbonMonoxidePeakLevel() *CarbonMonoxidePeakLevel { 11 | char := NewFloat(TypeCarbonMonoxidePeakLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | 17 | char.SetValue(0) 18 | 19 | return &CarbonMonoxidePeakLevel{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/category.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCategory = "A3" 5 | 6 | type Category struct { 7 | *Int 8 | } 9 | 10 | func NewCategory() *Category { 11 | char := NewInt(TypeCategory) 12 | char.Format = FormatUInt16 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(1) 15 | char.SetMaxValue(16) 16 | char.SetStepValue(1) 17 | char.SetValue(1) 18 | 19 | return &Category{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/charging_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ChargingStateNotCharging int = 0 6 | ChargingStateCharging int = 1 7 | ChargingStateNotChargeable int = 2 8 | ) 9 | 10 | const TypeChargingState = "8F" 11 | 12 | type ChargingState struct { 13 | *Int 14 | } 15 | 16 | func NewChargingState() *ChargingState { 17 | char := NewInt(TypeChargingState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &ChargingState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/closed_captions.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ClosedCaptionsDisabled int = 0 6 | ClosedCaptionsEnabled int = 1 7 | ) 8 | 9 | const TypeClosedCaptions = "DD" 10 | 11 | type ClosedCaptions struct { 12 | *Int 13 | } 14 | 15 | func NewClosedCaptions() *ClosedCaptions { 16 | char := NewInt(TypeClosedCaptions) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | char.SetMinValue(0) 20 | char.SetMaxValue(1) 21 | char.SetStepValue(1) 22 | char.SetValue(0) 23 | 24 | return &ClosedCaptions{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/color_temperature.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeColorTemperature = "CE" 5 | 6 | type ColorTemperature struct { 7 | *Int 8 | } 9 | 10 | func NewColorTemperature() *ColorTemperature { 11 | char := NewInt(TypeColorTemperature) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(140) 15 | char.SetMaxValue(500) 16 | char.SetStepValue(1) 17 | char.SetValue(140) 18 | 19 | return &ColorTemperature{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/configure_bridged_accessory.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeConfigureBridgedAccessory = "A0" 5 | 6 | type ConfigureBridgedAccessory struct { 7 | *Bytes 8 | } 9 | 10 | func NewConfigureBridgedAccessory() *ConfigureBridgedAccessory { 11 | char := NewBytes(TypeConfigureBridgedAccessory) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermWrite} 14 | 15 | return &ConfigureBridgedAccessory{char} 16 | } 17 | -------------------------------------------------------------------------------- /characteristic/configure_bridged_accessory_status.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeConfigureBridgedAccessoryStatus = "9D" 5 | 6 | type ConfigureBridgedAccessoryStatus struct { 7 | *Bytes 8 | } 9 | 10 | func NewConfigureBridgedAccessoryStatus() *ConfigureBridgedAccessoryStatus { 11 | char := NewBytes(TypeConfigureBridgedAccessoryStatus) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &ConfigureBridgedAccessoryStatus{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/configured_name.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeConfiguredName = "E3" 5 | 6 | type ConfiguredName struct { 7 | *String 8 | } 9 | 10 | func NewConfiguredName() *ConfiguredName { 11 | char := NewString(TypeConfiguredName) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue("") 16 | 17 | return &ConfiguredName{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/contact_sensor_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ContactSensorStateContactDetected int = 0 6 | ContactSensorStateContactNotDetected int = 1 7 | ) 8 | 9 | const TypeContactSensorState = "6A" 10 | 11 | type ContactSensorState struct { 12 | *Int 13 | } 14 | 15 | func NewContactSensorState() *ContactSensorState { 16 | char := NewInt(TypeContactSensorState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &ContactSensorState{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/cooling_threshold_temperature.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCoolingThresholdTemperature = "D" 5 | 6 | type CoolingThresholdTemperature struct { 7 | *Float 8 | } 9 | 10 | func NewCoolingThresholdTemperature() *CoolingThresholdTemperature { 11 | char := NewFloat(TypeCoolingThresholdTemperature) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(10) 15 | char.SetMaxValue(35) 16 | char.SetStepValue(0.1) 17 | char.SetValue(10) 18 | char.Unit = UnitCelsius 19 | 20 | return &CoolingThresholdTemperature{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_air_purifier_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentAirPurifierStateInactive int = 0 6 | CurrentAirPurifierStateIdle int = 1 7 | CurrentAirPurifierStatePurifyingAir int = 2 8 | ) 9 | 10 | const TypeCurrentAirPurifierState = "A9" 11 | 12 | type CurrentAirPurifierState struct { 13 | *Int 14 | } 15 | 16 | func NewCurrentAirPurifierState() *CurrentAirPurifierState { 17 | char := NewInt(TypeCurrentAirPurifierState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &CurrentAirPurifierState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/current_ambient_light_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentAmbientLightLevel = "6B" 5 | 6 | type CurrentAmbientLightLevel struct { 7 | *Float 8 | } 9 | 10 | func NewCurrentAmbientLightLevel() *CurrentAmbientLightLevel { 11 | char := NewFloat(TypeCurrentAmbientLightLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0.0001) 15 | char.SetMaxValue(100000) 16 | 17 | char.SetValue(0.0001) 18 | char.Unit = UnitLux 19 | 20 | return &CurrentAmbientLightLevel{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_door_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentDoorStateOpen int = 0 6 | CurrentDoorStateClosed int = 1 7 | CurrentDoorStateOpening int = 2 8 | CurrentDoorStateClosing int = 3 9 | CurrentDoorStateStopped int = 4 10 | ) 11 | 12 | const TypeCurrentDoorState = "E" 13 | 14 | type CurrentDoorState struct { 15 | *Int 16 | } 17 | 18 | func NewCurrentDoorState() *CurrentDoorState { 19 | char := NewInt(TypeCurrentDoorState) 20 | char.Format = FormatUInt8 21 | char.Perms = []string{PermRead, PermEvents} 22 | 23 | char.SetValue(0) 24 | 25 | return &CurrentDoorState{char} 26 | } 27 | -------------------------------------------------------------------------------- /characteristic/current_fan_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentFanStateInactive int = 0 6 | CurrentFanStateIdle int = 1 7 | CurrentFanStateBlowingAir int = 2 8 | ) 9 | 10 | const TypeCurrentFanState = "AF" 11 | 12 | type CurrentFanState struct { 13 | *Int 14 | } 15 | 16 | func NewCurrentFanState() *CurrentFanState { 17 | char := NewInt(TypeCurrentFanState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &CurrentFanState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/current_heater_cooler_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentHeaterCoolerStateInactive int = 0 6 | CurrentHeaterCoolerStateIdle int = 1 7 | CurrentHeaterCoolerStateHeating int = 2 8 | CurrentHeaterCoolerStateCooling int = 3 9 | ) 10 | 11 | const TypeCurrentHeaterCoolerState = "B1" 12 | 13 | type CurrentHeaterCoolerState struct { 14 | *Int 15 | } 16 | 17 | func NewCurrentHeaterCoolerState() *CurrentHeaterCoolerState { 18 | char := NewInt(TypeCurrentHeaterCoolerState) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermEvents} 21 | 22 | char.SetValue(0) 23 | 24 | return &CurrentHeaterCoolerState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/current_heating_cooling_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentHeatingCoolingStateOff int = 0 6 | CurrentHeatingCoolingStateHeat int = 1 7 | CurrentHeatingCoolingStateCool int = 2 8 | ) 9 | 10 | const TypeCurrentHeatingCoolingState = "F" 11 | 12 | type CurrentHeatingCoolingState struct { 13 | *Int 14 | } 15 | 16 | func NewCurrentHeatingCoolingState() *CurrentHeatingCoolingState { 17 | char := NewInt(TypeCurrentHeatingCoolingState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &CurrentHeatingCoolingState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/current_horizontal_tilt_angle.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentHorizontalTiltAngle = "6C" 5 | 6 | type CurrentHorizontalTiltAngle struct { 7 | *Int 8 | } 9 | 10 | func NewCurrentHorizontalTiltAngle() *CurrentHorizontalTiltAngle { 11 | char := NewInt(TypeCurrentHorizontalTiltAngle) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(-90) 15 | char.SetMaxValue(90) 16 | char.SetStepValue(1) 17 | char.SetValue(-90) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &CurrentHorizontalTiltAngle{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_humidifier_dehumidifier_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentHumidifierDehumidifierStateInactive int = 0 6 | CurrentHumidifierDehumidifierStateIdle int = 1 7 | CurrentHumidifierDehumidifierStateHumidifying int = 2 8 | CurrentHumidifierDehumidifierStateDehumidifying int = 3 9 | ) 10 | 11 | const TypeCurrentHumidifierDehumidifierState = "B3" 12 | 13 | type CurrentHumidifierDehumidifierState struct { 14 | *Int 15 | } 16 | 17 | func NewCurrentHumidifierDehumidifierState() *CurrentHumidifierDehumidifierState { 18 | char := NewInt(TypeCurrentHumidifierDehumidifierState) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermEvents} 21 | 22 | char.SetValue(0) 23 | 24 | return &CurrentHumidifierDehumidifierState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/current_media_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentMediaStatePlay int = 0 6 | CurrentMediaStatePause int = 1 7 | CurrentMediaStateStop int = 2 8 | CurrentMediaStateUnknown int = 3 9 | ) 10 | 11 | const TypeCurrentMediaState = "E0" 12 | 13 | type CurrentMediaState struct { 14 | *Int 15 | } 16 | 17 | func NewCurrentMediaState() *CurrentMediaState { 18 | char := NewInt(TypeCurrentMediaState) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermEvents} 21 | char.SetMinValue(0) 22 | char.SetMaxValue(3) 23 | char.SetStepValue(1) 24 | char.SetValue(0) 25 | char.Unit = UnitPercentage 26 | 27 | return &CurrentMediaState{char} 28 | } 29 | -------------------------------------------------------------------------------- /characteristic/current_position.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentPosition = "6D" 5 | 6 | type CurrentPosition struct { 7 | *Int 8 | } 9 | 10 | func NewCurrentPosition() *CurrentPosition { 11 | char := NewInt(TypeCurrentPosition) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &CurrentPosition{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_relative_humidity.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentRelativeHumidity = "10" 5 | 6 | type CurrentRelativeHumidity struct { 7 | *Float 8 | } 9 | 10 | func NewCurrentRelativeHumidity() *CurrentRelativeHumidity { 11 | char := NewFloat(TypeCurrentRelativeHumidity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &CurrentRelativeHumidity{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_slat_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentSlatStateFixed int = 0 6 | CurrentSlatStateJammed int = 1 7 | CurrentSlatStateSwinging int = 2 8 | ) 9 | 10 | const TypeCurrentSlatState = "AA" 11 | 12 | type CurrentSlatState struct { 13 | *Int 14 | } 15 | 16 | func NewCurrentSlatState() *CurrentSlatState { 17 | char := NewInt(TypeCurrentSlatState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &CurrentSlatState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/current_temperature.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentTemperature = "11" 5 | 6 | type CurrentTemperature struct { 7 | *Float 8 | } 9 | 10 | func NewCurrentTemperature() *CurrentTemperature { 11 | char := NewFloat(TypeCurrentTemperature) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(0.1) 17 | char.SetValue(0) 18 | char.Unit = UnitCelsius 19 | 20 | return &CurrentTemperature{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_tilt_angle.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentTiltAngle = "C1" 5 | 6 | type CurrentTiltAngle struct { 7 | *Int 8 | } 9 | 10 | func NewCurrentTiltAngle() *CurrentTiltAngle { 11 | char := NewInt(TypeCurrentTiltAngle) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(-90) 15 | char.SetMaxValue(90) 16 | char.SetStepValue(1) 17 | char.SetValue(-90) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &CurrentTiltAngle{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_time.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentTime = "9B" 5 | 6 | type CurrentTime struct { 7 | *String 8 | } 9 | 10 | func NewCurrentTime() *CurrentTime { 11 | char := NewString(TypeCurrentTime) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue("") 16 | 17 | return &CurrentTime{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/current_transport.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | const TypeCurrentTransport = "22B" 4 | 5 | type CurrentTransport struct { 6 | *Bool 7 | } 8 | 9 | func NewCurrentTransport() *CurrentTransport { 10 | char := NewBool(TypeCurrentTransport) 11 | char.Format = FormatBool 12 | char.Perms = []string{PermRead} 13 | 14 | char.SetValue(false) 15 | 16 | return &CurrentTransport{char} 17 | } 18 | -------------------------------------------------------------------------------- /characteristic/current_vertical_tilt_angle.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeCurrentVerticalTiltAngle = "6E" 5 | 6 | type CurrentVerticalTiltAngle struct { 7 | *Int 8 | } 9 | 10 | func NewCurrentVerticalTiltAngle() *CurrentVerticalTiltAngle { 11 | char := NewInt(TypeCurrentVerticalTiltAngle) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(-90) 15 | char.SetMaxValue(90) 16 | char.SetStepValue(1) 17 | char.SetValue(-90) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &CurrentVerticalTiltAngle{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/current_visibility_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | CurrentVisibilityStateShown int = 0 6 | CurrentVisibilityStateHidden int = 1 7 | ) 8 | 9 | const TypeCurrentVisibilityState = "135" 10 | 11 | type CurrentVisibilityState struct { 12 | *Int 13 | } 14 | 15 | func NewCurrentVisibilityState() *CurrentVisibilityState { 16 | char := NewInt(TypeCurrentVisibilityState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | char.SetMinValue(0) 20 | char.SetMaxValue(3) 21 | char.SetStepValue(1) 22 | char.SetValue(0) 23 | 24 | return &CurrentVisibilityState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/day_of_the_week.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeDayOfTheWeek = "98" 5 | 6 | type DayOfTheWeek struct { 7 | *Int 8 | } 9 | 10 | func NewDayOfTheWeek() *DayOfTheWeek { 11 | char := NewInt(TypeDayOfTheWeek) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermWrite} 14 | char.SetMinValue(1) 15 | char.SetMaxValue(7) 16 | char.SetStepValue(1) 17 | char.SetValue(1) 18 | 19 | return &DayOfTheWeek{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/digital_zoom.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeDigitalZoom = "11D" 5 | 6 | type DigitalZoom struct { 7 | *Float 8 | } 9 | 10 | func NewDigitalZoom() *DigitalZoom { 11 | char := NewFloat(TypeDigitalZoom) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(0) 16 | 17 | return &DigitalZoom{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/discover_bridged_accessories.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | DiscoverBridgedAccessoriesStartDiscovery int = 0 6 | DiscoverBridgedAccessoriesStopDiscovery int = 1 7 | ) 8 | 9 | const TypeDiscoverBridgedAccessories = "9E" 10 | 11 | type DiscoverBridgedAccessories struct { 12 | *Int 13 | } 14 | 15 | func NewDiscoverBridgedAccessories() *DiscoverBridgedAccessories { 16 | char := NewInt(TypeDiscoverBridgedAccessories) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &DiscoverBridgedAccessories{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/discovered_bridged_accessories.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeDiscoveredBridgedAccessories = "9F" 5 | 6 | type DiscoveredBridgedAccessories struct { 7 | *Int 8 | } 9 | 10 | func NewDiscoveredBridgedAccessories() *DiscoveredBridgedAccessories { 11 | char := NewInt(TypeDiscoveredBridgedAccessories) 12 | char.Format = FormatUInt16 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(0) 16 | 17 | return &DiscoveredBridgedAccessories{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/display_order.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeDisplayOrder = "136" 5 | 6 | type DisplayOrder struct { 7 | *Bytes 8 | } 9 | 10 | func NewDisplayOrder() *DisplayOrder { 11 | char := NewBytes(TypeDisplayOrder) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &DisplayOrder{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/doc.go: -------------------------------------------------------------------------------- 1 | // Package characteristic implements the HomeKit characteristics. 2 | package characteristic 3 | -------------------------------------------------------------------------------- /characteristic/filter_change_indication.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | FilterChangeIndicationFilterOK int = 0 6 | FilterChangeIndicationChangeFilter int = 1 7 | ) 8 | 9 | const TypeFilterChangeIndication = "AC" 10 | 11 | type FilterChangeIndication struct { 12 | *Int 13 | } 14 | 15 | func NewFilterChangeIndication() *FilterChangeIndication { 16 | char := NewInt(TypeFilterChangeIndication) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &FilterChangeIndication{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/filter_life_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeFilterLifeLevel = "AB" 5 | 6 | type FilterLifeLevel struct { 7 | *Float 8 | } 9 | 10 | func NewFilterLifeLevel() *FilterLifeLevel { 11 | char := NewFloat(TypeFilterLifeLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | 17 | char.SetValue(0) 18 | 19 | return &FilterLifeLevel{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/firmware_revision.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeFirmwareRevision = "52" 5 | 6 | type FirmwareRevision struct { 7 | *String 8 | } 9 | 10 | func NewFirmwareRevision() *FirmwareRevision { 11 | char := NewString(TypeFirmwareRevision) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &FirmwareRevision{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/float_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestFloat(t *testing.T) { 8 | float := NewHue() 9 | float.Value = 20.2 10 | 11 | if is, want := float.GetValue(), 20.2; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | 15 | float.SetValue(10.1) 16 | 17 | if is, want := float.GetValue(), 10.1; is != want { 18 | t.Fatalf("is=%v want=%v", is, want) 19 | } 20 | } 21 | 22 | func TestNumberFloatOutOfBounds(t *testing.T) { 23 | float := NewHue() 24 | 25 | float.SetValue(400) 26 | if is, want := float.GetValue(), 360.0; is != want { 27 | t.Fatalf("is=%v want=%v", is, want) 28 | } 29 | 30 | float.SetValue(-40) 31 | if is, want := float.GetValue(), 0.0; is != want { 32 | t.Fatalf("is=%v want=%v", is, want) 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /characteristic/hardware_revision.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeHardwareRevision = "53" 5 | 6 | type HardwareRevision struct { 7 | *String 8 | } 9 | 10 | func NewHardwareRevision() *HardwareRevision { 11 | char := NewString(TypeHardwareRevision) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &HardwareRevision{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/heating_cooling_mode_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestHeatingCoolingMode(t *testing.T) { 8 | b := NewCurrentHeatingCoolingState() 9 | b.Value = CurrentHeatingCoolingStateOff 10 | 11 | if is, want := b.GetValue(), CurrentHeatingCoolingStateOff; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | 15 | b.SetValue(CurrentHeatingCoolingStateHeat) 16 | 17 | if is, want := b.GetValue(), CurrentHeatingCoolingStateHeat; is != want { 18 | t.Fatalf("is=%v want=%v", is, want) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/heating_threshold_temperature.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeHeatingThresholdTemperature = "12" 5 | 6 | type HeatingThresholdTemperature struct { 7 | *Float 8 | } 9 | 10 | func NewHeatingThresholdTemperature() *HeatingThresholdTemperature { 11 | char := NewFloat(TypeHeatingThresholdTemperature) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(25) 16 | char.SetStepValue(0.1) 17 | char.SetValue(0) 18 | char.Unit = UnitCelsius 19 | 20 | return &HeatingThresholdTemperature{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/hold_position.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeHoldPosition = "6F" 5 | 6 | type HoldPosition struct { 7 | *Bool 8 | } 9 | 10 | func NewHoldPosition() *HoldPosition { 11 | char := NewBool(TypeHoldPosition) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermWrite} 14 | 15 | return &HoldPosition{char} 16 | } 17 | -------------------------------------------------------------------------------- /characteristic/hue.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeHue = "13" 5 | 6 | type Hue struct { 7 | *Float 8 | } 9 | 10 | func NewHue() *Hue { 11 | char := NewFloat(TypeHue) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(360) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &Hue{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/identifier.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeIdentifier = "E6" 5 | 6 | type Identifier struct { 7 | *Int 8 | } 9 | 10 | func NewIdentifier() *Identifier { 11 | char := NewInt(TypeIdentifier) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead} 14 | char.SetMinValue(0) 15 | 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &Identifier{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/identify.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeIdentify = "14" 5 | 6 | type Identify struct { 7 | *Bool 8 | } 9 | 10 | func NewIdentify() *Identify { 11 | char := NewBool(TypeIdentify) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermWrite} 14 | 15 | return &Identify{char} 16 | } 17 | -------------------------------------------------------------------------------- /characteristic/image_mirroring.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeImageMirroring = "11F" 5 | 6 | type ImageMirroring struct { 7 | *Bool 8 | } 9 | 10 | func NewImageMirroring() *ImageMirroring { 11 | char := NewBool(TypeImageMirroring) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &ImageMirroring{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/image_rotation.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeImageRotation = "11E" 5 | 6 | type ImageRotation struct { 7 | *Float 8 | } 9 | 10 | func NewImageRotation() *ImageRotation { 11 | char := NewFloat(TypeImageRotation) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(270) 16 | char.SetStepValue(90) 17 | char.SetValue(0) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &ImageRotation{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/in_use.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | InUseNotInUse int = 0 6 | InUseInUse int = 1 7 | ) 8 | 9 | const TypeInUse = "D2" 10 | 11 | type InUse struct { 12 | *Int 13 | } 14 | 15 | func NewInUse() *InUse { 16 | char := NewInt(TypeInUse) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &InUse{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/input_device_type.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | InputDeviceTypeOther int = 0 6 | InputDeviceTypeTv int = 1 7 | InputDeviceTypeRecording int = 2 8 | InputDeviceTypeTuner int = 3 9 | InputDeviceTypePlayback int = 4 10 | InputDeviceTypeAudioSystem int = 5 11 | ) 12 | 13 | const TypeInputDeviceType = "DC" 14 | 15 | type InputDeviceType struct { 16 | *Int 17 | } 18 | 19 | func NewInputDeviceType() *InputDeviceType { 20 | char := NewInt(TypeInputDeviceType) 21 | char.Format = FormatUInt8 22 | char.Perms = []string{PermRead, PermEvents} 23 | char.SetMinValue(0) 24 | char.SetMaxValue(5) 25 | char.SetStepValue(1) 26 | char.SetValue(0) 27 | 28 | return &InputDeviceType{char} 29 | } 30 | -------------------------------------------------------------------------------- /characteristic/input_source_type.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | InputSourceTypeOther int = 0 6 | InputSourceTypeHomeScreen int = 1 7 | InputSourceTypeApplication int = 10 8 | InputSourceTypeTuner int = 2 9 | InputSourceTypeHdmi int = 3 10 | InputSourceTypeCompositeVideo int = 4 11 | InputSourceTypeSVideo int = 5 12 | InputSourceTypeComponentVideo int = 6 13 | InputSourceTypeDvi int = 7 14 | InputSourceTypeAirplay int = 8 15 | InputSourceTypeUsb int = 9 16 | ) 17 | 18 | const TypeInputSourceType = "DB" 19 | 20 | type InputSourceType struct { 21 | *Int 22 | } 23 | 24 | func NewInputSourceType() *InputSourceType { 25 | char := NewInt(TypeInputSourceType) 26 | char.Format = FormatUInt8 27 | char.Perms = []string{PermRead, PermEvents} 28 | char.SetMinValue(0) 29 | char.SetMaxValue(10) 30 | char.SetStepValue(1) 31 | char.SetValue(0) 32 | 33 | return &InputSourceType{char} 34 | } 35 | -------------------------------------------------------------------------------- /characteristic/int_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestNumberIntOutOfBounds(t *testing.T) { 8 | number := NewBrightness() 9 | number.SetValue(120) 10 | if is, want := number.GetValue(), 100; is != want { 11 | t.Fatalf("is=%v want=%v", is, want) 12 | } 13 | 14 | number.SetValue(-40) 15 | if is, want := number.GetValue(), 0; is != want { 16 | t.Fatalf("is=%v want=%v", is, want) 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/is_configured.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | IsConfiguredNotConfigured int = 0 6 | IsConfiguredConfigured int = 1 7 | ) 8 | 9 | const TypeIsConfigured = "D6" 10 | 11 | type IsConfigured struct { 12 | *Int 13 | } 14 | 15 | func NewIsConfigured() *IsConfigured { 16 | char := NewInt(TypeIsConfigured) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &IsConfigured{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/leak_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | LeakDetectedLeakNotDetected int = 0 6 | LeakDetectedLeakDetected int = 1 7 | ) 8 | 9 | const TypeLeakDetected = "70" 10 | 11 | type LeakDetected struct { 12 | *Int 13 | } 14 | 15 | func NewLeakDetected() *LeakDetected { 16 | char := NewInt(TypeLeakDetected) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &LeakDetected{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/link_quality.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeLinkQuality = "9C" 5 | 6 | type LinkQuality struct { 7 | *Int 8 | } 9 | 10 | func NewLinkQuality() *LinkQuality { 11 | char := NewInt(TypeLinkQuality) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(1) 15 | char.SetMaxValue(4) 16 | char.SetStepValue(1) 17 | char.SetValue(1) 18 | 19 | return &LinkQuality{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/lock_control_point.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeLockControlPoint = "19" 5 | 6 | type LockControlPoint struct { 7 | *Bytes 8 | } 9 | 10 | func NewLockControlPoint() *LockControlPoint { 11 | char := NewBytes(TypeLockControlPoint) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermWrite} 14 | 15 | return &LockControlPoint{char} 16 | } 17 | -------------------------------------------------------------------------------- /characteristic/lock_current_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | LockCurrentStateUnsecured int = 0 6 | LockCurrentStateSecured int = 1 7 | LockCurrentStateJammed int = 2 8 | LockCurrentStateUnknown int = 3 9 | ) 10 | 11 | const TypeLockCurrentState = "1D" 12 | 13 | type LockCurrentState struct { 14 | *Int 15 | } 16 | 17 | func NewLockCurrentState() *LockCurrentState { 18 | char := NewInt(TypeLockCurrentState) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermEvents} 21 | 22 | char.SetValue(0) 23 | 24 | return &LockCurrentState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/lock_last_known_action.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | LockLastKnownActionSecuredPhysicallyInterior int = 0 6 | LockLastKnownActionUnsecuredPhysicallyInterior int = 1 7 | LockLastKnownActionSecuredPhysicallyExterior int = 2 8 | LockLastKnownActionUnsecuredPhysicallyExterior int = 3 9 | LockLastKnownActionSecuredByKeypad int = 4 10 | LockLastKnownActionUnsecuredByKeypad int = 5 11 | LockLastKnownActionSecuredRemotely int = 6 12 | LockLastKnownActionUnsecuredRemotely int = 7 13 | LockLastKnownActionSecuredByAutoSecureTimeout int = 8 14 | ) 15 | 16 | const TypeLockLastKnownAction = "1C" 17 | 18 | type LockLastKnownAction struct { 19 | *Int 20 | } 21 | 22 | func NewLockLastKnownAction() *LockLastKnownAction { 23 | char := NewInt(TypeLockLastKnownAction) 24 | char.Format = FormatUInt8 25 | char.Perms = []string{PermRead, PermEvents} 26 | 27 | char.SetValue(0) 28 | 29 | return &LockLastKnownAction{char} 30 | } 31 | -------------------------------------------------------------------------------- /characteristic/lock_management_auto_security_timeout.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeLockManagementAutoSecurityTimeout = "1A" 5 | 6 | type LockManagementAutoSecurityTimeout struct { 7 | *Int 8 | } 9 | 10 | func NewLockManagementAutoSecurityTimeout() *LockManagementAutoSecurityTimeout { 11 | char := NewInt(TypeLockManagementAutoSecurityTimeout) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(0) 16 | char.Unit = UnitSeconds 17 | 18 | return &LockManagementAutoSecurityTimeout{char} 19 | } 20 | -------------------------------------------------------------------------------- /characteristic/lock_physical_controls.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | LockPhysicalControlsControlLockDisabled int = 0 6 | LockPhysicalControlsControlLockEnabled int = 1 7 | ) 8 | 9 | const TypeLockPhysicalControls = "A7" 10 | 11 | type LockPhysicalControls struct { 12 | *Int 13 | } 14 | 15 | func NewLockPhysicalControls() *LockPhysicalControls { 16 | char := NewInt(TypeLockPhysicalControls) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &LockPhysicalControls{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/lock_target_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | LockTargetStateUnsecured int = 0 6 | LockTargetStateSecured int = 1 7 | ) 8 | 9 | const TypeLockTargetState = "1E" 10 | 11 | type LockTargetState struct { 12 | *Int 13 | } 14 | 15 | func NewLockTargetState() *LockTargetState { 16 | char := NewInt(TypeLockTargetState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &LockTargetState{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/logs.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeLogs = "1F" 5 | 6 | type Logs struct { 7 | *Bytes 8 | } 9 | 10 | func NewLogs() *Logs { 11 | char := NewBytes(TypeLogs) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &Logs{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/manufacturer.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeManufacturer = "20" 5 | 6 | type Manufacturer struct { 7 | *String 8 | } 9 | 10 | func NewManufacturer() *Manufacturer { 11 | char := NewString(TypeManufacturer) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &Manufacturer{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/manufacturer_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestManufacturer(t *testing.T) { 8 | m := NewManufacturer() 9 | m.Value = "Apple" 10 | 11 | if is, want := m.Type, TypeManufacturer; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | if is, want := m.GetValue(), "Apple"; is != want { 15 | t.Fatalf("is=%v want=%v", is, want) 16 | } 17 | 18 | m.SetValue("Google") 19 | 20 | if is, want := m.GetValue(), "Google"; is != want { 21 | t.Fatalf("is=%v want=%v", is, want) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/model.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeModel = "21" 5 | 6 | type Model struct { 7 | *String 8 | } 9 | 10 | func NewModel() *Model { 11 | char := NewString(TypeModel) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &Model{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/model_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestModel(t *testing.T) { 8 | m := NewModel() 9 | m.Value = "Late 2014" 10 | 11 | if is, want := m.Type, TypeModel; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | if is, want := m.GetValue(), "Late 2014"; is != want { 15 | t.Fatalf("is=%v want=%v", is, want) 16 | } 17 | 18 | m.SetValue("Early 2015") 19 | 20 | if is, want := m.GetValue(), "Early 2015"; is != want { 21 | t.Fatalf("is=%v want=%v", is, want) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/motion_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeMotionDetected = "22" 5 | 6 | type MotionDetected struct { 7 | *Bool 8 | } 9 | 10 | func NewMotionDetected() *MotionDetected { 11 | char := NewBool(TypeMotionDetected) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &MotionDetected{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/mute.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeMute = "11A" 5 | 6 | type Mute struct { 7 | *Bool 8 | } 9 | 10 | func NewMute() *Mute { 11 | char := NewBool(TypeMute) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &Mute{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/name.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeName = "23" 5 | 6 | type Name struct { 7 | *String 8 | } 9 | 10 | func NewName() *Name { 11 | char := NewString(TypeName) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &Name{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/name_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestName(t *testing.T) { 8 | n := NewName() 9 | n.Value = "Test" 10 | 11 | if is, want := n.Type, TypeName; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | if is, want := n.GetValue(), "Test"; is != want { 15 | t.Fatalf("is=%v want=%v", is, want) 16 | } 17 | 18 | n.SetValue("My Name") 19 | 20 | if is, want := n.GetValue(), "My Name"; is != want { 21 | t.Fatalf("is=%v want=%v", is, want) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/night_vision.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeNightVision = "11B" 5 | 6 | type NightVision struct { 7 | *Bool 8 | } 9 | 10 | func NewNightVision() *NightVision { 11 | char := NewBool(TypeNightVision) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &NightVision{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/nitrogen_dioxide_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeNitrogenDioxideDensity = "C4" 5 | 6 | type NitrogenDioxideDensity struct { 7 | *Float 8 | } 9 | 10 | func NewNitrogenDioxideDensity() *NitrogenDioxideDensity { 11 | char := NewFloat(TypeNitrogenDioxideDensity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &NitrogenDioxideDensity{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/obstruction_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeObstructionDetected = "24" 5 | 6 | type ObstructionDetected struct { 7 | *Bool 8 | } 9 | 10 | func NewObstructionDetected() *ObstructionDetected { 11 | char := NewBool(TypeObstructionDetected) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &ObstructionDetected{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/occupancy_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | OccupancyDetectedOccupancyNotDetected int = 0 6 | OccupancyDetectedOccupancyDetected int = 1 7 | ) 8 | 9 | const TypeOccupancyDetected = "71" 10 | 11 | type OccupancyDetected struct { 12 | *Int 13 | } 14 | 15 | func NewOccupancyDetected() *OccupancyDetected { 16 | char := NewInt(TypeOccupancyDetected) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &OccupancyDetected{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/on.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeOn = "25" 5 | 6 | type On struct { 7 | *Bool 8 | } 9 | 10 | func NewOn() *On { 11 | char := NewBool(TypeOn) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &On{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/on_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestOn(t *testing.T) { 8 | b := NewOn() 9 | b.Value = true 10 | 11 | if is, want := b.GetValue(), true; is != want { 12 | t.Fatalf("is=%v want=%v", is, want) 13 | } 14 | 15 | b.SetValue(false) 16 | 17 | if is, want := b.GetValue(), false; is != want { 18 | t.Fatalf("is=%v want=%v", is, want) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/optical_zoom.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeOpticalZoom = "11C" 5 | 6 | type OpticalZoom struct { 7 | *Float 8 | } 9 | 10 | func NewOpticalZoom() *OpticalZoom { 11 | char := NewFloat(TypeOpticalZoom) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue(0) 16 | 17 | return &OpticalZoom{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/outlet_in_use.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeOutletInUse = "26" 5 | 6 | type OutletInUse struct { 7 | *Bool 8 | } 9 | 10 | func NewOutletInUse() *OutletInUse { 11 | char := NewBool(TypeOutletInUse) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &OutletInUse{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/ozone_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeOzoneDensity = "C3" 5 | 6 | type OzoneDensity struct { 7 | *Float 8 | } 9 | 10 | func NewOzoneDensity() *OzoneDensity { 11 | char := NewFloat(TypeOzoneDensity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &OzoneDensity{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/pair_setup.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypePairSetup = "4C" 5 | 6 | type PairSetup struct { 7 | *Bytes 8 | } 9 | 10 | func NewPairSetup() *PairSetup { 11 | char := NewBytes(TypePairSetup) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &PairSetup{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/pair_verify.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypePairVerify = "4E" 5 | 6 | type PairVerify struct { 7 | *Bytes 8 | } 9 | 10 | func NewPairVerify() *PairVerify { 11 | char := NewBytes(TypePairVerify) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &PairVerify{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/pairing_features.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypePairingFeatures = "4F" 5 | 6 | type PairingFeatures struct { 7 | *Int 8 | } 9 | 10 | func NewPairingFeatures() *PairingFeatures { 11 | char := NewInt(TypePairingFeatures) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue(0) 16 | 17 | return &PairingFeatures{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/pairing_pairings.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypePairingPairings = "50" 5 | 6 | type PairingPairings struct { 7 | *Bytes 8 | } 9 | 10 | func NewPairingPairings() *PairingPairings { 11 | char := NewBytes(TypePairingPairings) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &PairingPairings{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/picture_mode.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | PictureModeOther int = 0 6 | PictureModeStandard int = 1 7 | PictureModeCalibrated int = 2 8 | PictureModeCalibratedDark int = 3 9 | PictureModeVivid int = 4 10 | PictureModeGame int = 5 11 | PictureModeComputer int = 6 12 | PictureModeCustom int = 7 13 | ) 14 | 15 | const TypePictureMode = "E2" 16 | 17 | type PictureMode struct { 18 | *Int 19 | } 20 | 21 | func NewPictureMode() *PictureMode { 22 | char := NewInt(TypePictureMode) 23 | char.Format = FormatUInt16 24 | char.Perms = []string{PermRead, PermWrite, PermEvents} 25 | char.SetMinValue(0) 26 | char.SetMaxValue(13) 27 | char.SetStepValue(1) 28 | char.SetValue(0) 29 | 30 | return &PictureMode{char} 31 | } 32 | -------------------------------------------------------------------------------- /characteristic/pm10_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypePM10Density = "C7" 5 | 6 | type PM10Density struct { 7 | *Float 8 | } 9 | 10 | func NewPM10Density() *PM10Density { 11 | char := NewFloat(TypePM10Density) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &PM10Density{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/pm2_5_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypePM2_5Density = "C6" 5 | 6 | type PM2_5Density struct { 7 | *Float 8 | } 9 | 10 | func NewPM2_5Density() *PM2_5Density { 11 | char := NewFloat(TypePM2_5Density) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &PM2_5Density{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/position_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | PositionStateDecreasing int = 0 6 | PositionStateIncreasing int = 1 7 | PositionStateStopped int = 2 8 | ) 9 | 10 | const TypePositionState = "72" 11 | 12 | type PositionState struct { 13 | *Int 14 | } 15 | 16 | func NewPositionState() *PositionState { 17 | char := NewInt(TypePositionState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &PositionState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/power_mode_selection.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | PowerModeSelectionShow int = 0 6 | PowerModeSelectionHide int = 1 7 | ) 8 | 9 | const TypePowerModeSelection = "DF" 10 | 11 | type PowerModeSelection struct { 12 | *Int 13 | } 14 | 15 | func NewPowerModeSelection() *PowerModeSelection { 16 | char := NewInt(TypePowerModeSelection) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermWrite} 19 | char.SetMinValue(0) 20 | char.SetMaxValue(1) 21 | char.SetStepValue(1) 22 | 23 | return &PowerModeSelection{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/program_mode.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ProgramModeNoProgramScheduled int = 0 6 | ProgramModeProgramScheduled int = 1 7 | ProgramModeProgramScheduledManualMode int = 2 8 | ) 9 | 10 | const TypeProgramMode = "D1" 11 | 12 | type ProgramMode struct { 13 | *Int 14 | } 15 | 16 | func NewProgramMode() *ProgramMode { 17 | char := NewInt(TypeProgramMode) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &ProgramMode{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/programmable_switch_event.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ProgrammableSwitchEventSinglePress int = 0 6 | ProgrammableSwitchEventDoublePress int = 1 7 | ProgrammableSwitchEventLongPress int = 2 8 | ) 9 | 10 | const TypeProgrammableSwitchEvent = "73" 11 | 12 | type ProgrammableSwitchEvent struct { 13 | *Int 14 | } 15 | 16 | func NewProgrammableSwitchEvent() *ProgrammableSwitchEvent { 17 | char := NewInt(TypeProgrammableSwitchEvent) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | char.updateOnSameValue = true 24 | 25 | return &ProgrammableSwitchEvent{char} 26 | } 27 | -------------------------------------------------------------------------------- /characteristic/programmable_switch_output_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeProgrammableSwitchOutputState = "74" 5 | 6 | type ProgrammableSwitchOutputState struct { 7 | *Int 8 | } 9 | 10 | func NewProgrammableSwitchOutputState() *ProgrammableSwitchOutputState { 11 | char := NewInt(TypeProgrammableSwitchOutputState) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &ProgrammableSwitchOutputState{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/reachable.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeReachable = "63" 5 | 6 | type Reachable struct { 7 | *Bool 8 | } 9 | 10 | func NewReachable() *Reachable { 11 | char := NewBool(TypeReachable) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &Reachable{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/relative_humidity_dehumidifier_threshold.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeRelativeHumidityDehumidifierThreshold = "C9" 5 | 6 | type RelativeHumidityDehumidifierThreshold struct { 7 | *Float 8 | } 9 | 10 | func NewRelativeHumidityDehumidifierThreshold() *RelativeHumidityDehumidifierThreshold { 11 | char := NewFloat(TypeRelativeHumidityDehumidifierThreshold) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &RelativeHumidityDehumidifierThreshold{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/relative_humidity_humidifier_threshold.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeRelativeHumidityHumidifierThreshold = "CA" 5 | 6 | type RelativeHumidityHumidifierThreshold struct { 7 | *Float 8 | } 9 | 10 | func NewRelativeHumidityHumidifierThreshold() *RelativeHumidityHumidifierThreshold { 11 | char := NewFloat(TypeRelativeHumidityHumidifierThreshold) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &RelativeHumidityHumidifierThreshold{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/remaining_duration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeRemainingDuration = "D4" 5 | 6 | type RemainingDuration struct { 7 | *Int 8 | } 9 | 10 | func NewRemainingDuration() *RemainingDuration { 11 | char := NewInt(TypeRemainingDuration) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(3600) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &RemainingDuration{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/remote_key.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | RemoteKeyRewind int = 0 6 | RemoteKeyFastForward int = 1 7 | RemoteKeyExit int = 10 8 | RemoteKeyPlayPause int = 11 9 | RemoteKeyInfo int = 15 10 | RemoteKeyNextTrack int = 2 11 | RemoteKeyPrevTrack int = 3 12 | RemoteKeyArrowUp int = 4 13 | RemoteKeyArrowDown int = 5 14 | RemoteKeyArrowLeft int = 6 15 | RemoteKeyArrowRight int = 7 16 | RemoteKeySelect int = 8 17 | RemoteKeyBack int = 9 18 | ) 19 | 20 | const TypeRemoteKey = "E1" 21 | 22 | type RemoteKey struct { 23 | *Int 24 | } 25 | 26 | func NewRemoteKey() *RemoteKey { 27 | char := NewInt(TypeRemoteKey) 28 | char.Format = FormatUInt8 29 | char.Perms = []string{PermWrite} 30 | char.SetMinValue(0) 31 | char.SetMaxValue(16) 32 | char.SetStepValue(1) 33 | 34 | return &RemoteKey{char} 35 | } 36 | -------------------------------------------------------------------------------- /characteristic/reset_filter_indication.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeResetFilterIndication = "AD" 5 | 6 | type ResetFilterIndication struct { 7 | *Int 8 | } 9 | 10 | func NewResetFilterIndication() *ResetFilterIndication { 11 | char := NewInt(TypeResetFilterIndication) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermWrite} 14 | char.SetMinValue(1) 15 | char.SetMaxValue(1) 16 | char.SetStepValue(1) 17 | 18 | return &ResetFilterIndication{char} 19 | } 20 | -------------------------------------------------------------------------------- /characteristic/rotation_direction.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | RotationDirectionClockwise int = 0 6 | RotationDirectionCounterclockwise int = 1 7 | ) 8 | 9 | const TypeRotationDirection = "28" 10 | 11 | type RotationDirection struct { 12 | *Int 13 | } 14 | 15 | func NewRotationDirection() *RotationDirection { 16 | char := NewInt(TypeRotationDirection) 17 | char.Format = FormatInt32 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &RotationDirection{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/rotation_speed.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeRotationSpeed = "29" 5 | 6 | type RotationSpeed struct { 7 | *Float 8 | } 9 | 10 | func NewRotationSpeed() *RotationSpeed { 11 | char := NewFloat(TypeRotationSpeed) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &RotationSpeed{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/saturation.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSaturation = "2F" 5 | 6 | type Saturation struct { 7 | *Float 8 | } 9 | 10 | func NewSaturation() *Saturation { 11 | char := NewFloat(TypeSaturation) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &Saturation{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/security_system_alarm_type.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSecuritySystemAlarmType = "8E" 5 | 6 | type SecuritySystemAlarmType struct { 7 | *Int 8 | } 9 | 10 | func NewSecuritySystemAlarmType() *SecuritySystemAlarmType { 11 | char := NewInt(TypeSecuritySystemAlarmType) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &SecuritySystemAlarmType{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/security_system_current_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | SecuritySystemCurrentStateStayArm int = 0 6 | SecuritySystemCurrentStateAwayArm int = 1 7 | SecuritySystemCurrentStateNightArm int = 2 8 | SecuritySystemCurrentStateDisarmed int = 3 9 | SecuritySystemCurrentStateAlarmTriggered int = 4 10 | ) 11 | 12 | const TypeSecuritySystemCurrentState = "66" 13 | 14 | type SecuritySystemCurrentState struct { 15 | *Int 16 | } 17 | 18 | func NewSecuritySystemCurrentState() *SecuritySystemCurrentState { 19 | char := NewInt(TypeSecuritySystemCurrentState) 20 | char.Format = FormatUInt8 21 | char.Perms = []string{PermRead, PermEvents} 22 | 23 | char.SetValue(0) 24 | 25 | return &SecuritySystemCurrentState{char} 26 | } 27 | -------------------------------------------------------------------------------- /characteristic/security_system_target_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | SecuritySystemTargetStateStayArm int = 0 6 | SecuritySystemTargetStateAwayArm int = 1 7 | SecuritySystemTargetStateNightArm int = 2 8 | SecuritySystemTargetStateDisarm int = 3 9 | ) 10 | 11 | const TypeSecuritySystemTargetState = "67" 12 | 13 | type SecuritySystemTargetState struct { 14 | *Int 15 | } 16 | 17 | func NewSecuritySystemTargetState() *SecuritySystemTargetState { 18 | char := NewInt(TypeSecuritySystemTargetState) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermWrite, PermEvents} 21 | 22 | char.SetValue(0) 23 | 24 | return &SecuritySystemTargetState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/selected_camera_recording_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSelectedCameraRecordingConfiguration = "209" 5 | 6 | type SelectedCameraRecordingConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSelectedCameraRecordingConfiguration() *SelectedCameraRecordingConfiguration { 11 | char := NewBytes(TypeSelectedCameraRecordingConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SelectedCameraRecordingConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/selected_rtp_stream_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSelectedRTPStreamConfiguration = "117" 5 | 6 | type SelectedRTPStreamConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSelectedRTPStreamConfiguration() *SelectedRTPStreamConfiguration { 11 | char := NewBytes(TypeSelectedRTPStreamConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SelectedRTPStreamConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/selected_stream_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSelectedStreamConfiguration = "117" 5 | 6 | type SelectedStreamConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSelectedStreamConfiguration() *SelectedStreamConfiguration { 11 | char := NewBytes(TypeSelectedStreamConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SelectedStreamConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/serial_number.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSerialNumber = "30" 5 | 6 | type SerialNumber struct { 7 | *String 8 | } 9 | 10 | func NewSerialNumber() *SerialNumber { 11 | char := NewString(TypeSerialNumber) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &SerialNumber{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/service_label_index.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeServiceLabelIndex = "CB" 5 | 6 | type ServiceLabelIndex struct { 7 | *Int 8 | } 9 | 10 | func NewServiceLabelIndex() *ServiceLabelIndex { 11 | char := NewInt(TypeServiceLabelIndex) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead} 14 | char.SetMinValue(1) 15 | char.SetMaxValue(255) 16 | char.SetStepValue(1) 17 | char.SetValue(1) 18 | 19 | return &ServiceLabelIndex{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/service_label_namespace.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ServiceLabelNamespaceDots int = 0 6 | ServiceLabelNamespaceArabicNumerals int = 1 7 | ) 8 | 9 | const TypeServiceLabelNamespace = "CD" 10 | 11 | type ServiceLabelNamespace struct { 12 | *Int 13 | } 14 | 15 | func NewServiceLabelNamespace() *ServiceLabelNamespace { 16 | char := NewInt(TypeServiceLabelNamespace) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead} 19 | 20 | char.SetValue(0) 21 | 22 | return &ServiceLabelNamespace{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/set_duration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSetDuration = "D3" 5 | 6 | type SetDuration struct { 7 | *Int 8 | } 9 | 10 | func NewSetDuration() *SetDuration { 11 | char := NewInt(TypeSetDuration) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(3600) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &SetDuration{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/setup_endpoints.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSetupEndpoints = "118" 5 | 6 | type SetupEndpoints struct { 7 | *Bytes 8 | } 9 | 10 | func NewSetupEndpoints() *SetupEndpoints { 11 | char := NewBytes(TypeSetupEndpoints) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermWrite} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SetupEndpoints{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/slat_type.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | SlatTypeHorizontal int = 0 6 | SlatTypeVertical int = 1 7 | ) 8 | 9 | const TypeSlatType = "C0" 10 | 11 | type SlatType struct { 12 | *Int 13 | } 14 | 15 | func NewSlatType() *SlatType { 16 | char := NewInt(TypeSlatType) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead} 19 | 20 | char.SetValue(0) 21 | 22 | return &SlatType{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/sleep_discovery_mode.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | SleepDiscoveryModeNotDiscoverable int = 0 6 | SleepDiscoveryModeAlwaysDiscoverable int = 1 7 | ) 8 | 9 | const TypeSleepDiscoveryMode = "E8" 10 | 11 | type SleepDiscoveryMode struct { 12 | *Int 13 | } 14 | 15 | func NewSleepDiscoveryMode() *SleepDiscoveryMode { 16 | char := NewInt(TypeSleepDiscoveryMode) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | char.SetMinValue(0) 20 | char.SetMaxValue(1) 21 | 22 | char.SetValue(0) 23 | 24 | return &SleepDiscoveryMode{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/smoke_detected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | SmokeDetectedSmokeNotDetected int = 0 6 | SmokeDetectedSmokeDetected int = 1 7 | ) 8 | 9 | const TypeSmokeDetected = "76" 10 | 11 | type SmokeDetected struct { 12 | *Int 13 | } 14 | 15 | func NewSmokeDetected() *SmokeDetected { 16 | char := NewInt(TypeSmokeDetected) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &SmokeDetected{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/software_revision.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSoftwareRevision = "54" 5 | 6 | type SoftwareRevision struct { 7 | *String 8 | } 9 | 10 | func NewSoftwareRevision() *SoftwareRevision { 11 | char := NewString(TypeSoftwareRevision) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue("") 16 | 17 | return &SoftwareRevision{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/status_active.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeStatusActive = "75" 5 | 6 | type StatusActive struct { 7 | *Bool 8 | } 9 | 10 | func NewStatusActive() *StatusActive { 11 | char := NewBool(TypeStatusActive) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &StatusActive{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/status_fault.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | StatusFaultNoFault int = 0 6 | StatusFaultGeneralFault int = 1 7 | ) 8 | 9 | const TypeStatusFault = "77" 10 | 11 | type StatusFault struct { 12 | *Int 13 | } 14 | 15 | func NewStatusFault() *StatusFault { 16 | char := NewInt(TypeStatusFault) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &StatusFault{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/status_jammed.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | StatusJammedNotJammed int = 0 6 | StatusJammedJammed int = 1 7 | ) 8 | 9 | const TypeStatusJammed = "78" 10 | 11 | type StatusJammed struct { 12 | *Int 13 | } 14 | 15 | func NewStatusJammed() *StatusJammed { 16 | char := NewInt(TypeStatusJammed) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &StatusJammed{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/status_low_battery.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | StatusLowBatteryBatteryLevelNormal int = 0 6 | StatusLowBatteryBatteryLevelLow int = 1 7 | ) 8 | 9 | const TypeStatusLowBattery = "79" 10 | 11 | type StatusLowBattery struct { 12 | *Int 13 | } 14 | 15 | func NewStatusLowBattery() *StatusLowBattery { 16 | char := NewInt(TypeStatusLowBattery) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &StatusLowBattery{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/status_tampered.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | StatusTamperedNotTampered int = 0 6 | StatusTamperedTampered int = 1 7 | ) 8 | 9 | const TypeStatusTampered = "7A" 10 | 11 | type StatusTampered struct { 12 | *Int 13 | } 14 | 15 | func NewStatusTampered() *StatusTampered { 16 | char := NewInt(TypeStatusTampered) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &StatusTampered{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/streaming_status.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeStreamingStatus = "120" 5 | 6 | type StreamingStatus struct { 7 | *Bytes 8 | } 9 | 10 | func NewStreamingStatus() *StreamingStatus { 11 | char := NewBytes(TypeStreamingStatus) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &StreamingStatus{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/string.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "net" 5 | ) 6 | 7 | type String struct { 8 | *Characteristic 9 | } 10 | 11 | func NewString(typ string) *String { 12 | char := NewCharacteristic(typ) 13 | char.Format = FormatString 14 | 15 | return &String{char} 16 | } 17 | 18 | // SetValue sets a value 19 | func (c *String) SetValue(str string) { 20 | c.UpdateValue(str) 21 | } 22 | 23 | // GetValue returns the value as string 24 | func (c *String) GetValue() string { 25 | return c.Characteristic.GetValue().(string) 26 | } 27 | 28 | // OnValueRemoteGet calls fn when the value was read by a client. 29 | func (c *String) OnValueRemoteGet(fn func() string) { 30 | c.OnValueGet(func() interface{} { 31 | return fn() 32 | }) 33 | } 34 | 35 | // OnValueRemoteUpdate calls fn when the value was updated by a client. 36 | func (c *String) OnValueRemoteUpdate(fn func(string)) { 37 | c.OnValueUpdateFromConn(func(conn net.Conn, c *Characteristic, new, old interface{}) { 38 | fn(new.(string)) 39 | }) 40 | } 41 | -------------------------------------------------------------------------------- /characteristic/string_test.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestString(t *testing.T) { 8 | str := NewString(TypeName) 9 | str.Perms = PermsAll() 10 | str.Value = "A String" 11 | 12 | if is, want := str.GetValue(), "A String"; is != want { 13 | t.Fatalf("is=%v want=%v", is, want) 14 | } 15 | 16 | str.SetValue("My String") 17 | 18 | if is, want := str.GetValue(), "My String"; is != want { 19 | t.Fatalf("is=%v want=%v", is, want) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/sulphur_dioxide_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSulphurDioxideDensity = "C5" 5 | 6 | type SulphurDioxideDensity struct { 7 | *Float 8 | } 9 | 10 | func NewSulphurDioxideDensity() *SulphurDioxideDensity { 11 | char := NewFloat(TypeSulphurDioxideDensity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &SulphurDioxideDensity{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/supported_audio_recording_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSupportedAudioRecordingConfiguration = "207" 5 | 6 | type SupportedAudioRecordingConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSupportedAudioRecordingConfiguration() *SupportedAudioRecordingConfiguration { 11 | char := NewBytes(TypeSupportedAudioRecordingConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SupportedAudioRecordingConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/supported_audio_stream_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSupportedAudioStreamConfiguration = "115" 5 | 6 | type SupportedAudioStreamConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSupportedAudioStreamConfiguration() *SupportedAudioStreamConfiguration { 11 | char := NewBytes(TypeSupportedAudioStreamConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SupportedAudioStreamConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/supported_camera_recording_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSupportedCameraRecordingConfiguration = "205" 5 | 6 | type SupportedCameraRecordingConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSupportedCameraRecordingConfiguration() *SupportedCameraRecordingConfiguration { 11 | char := NewBytes(TypeSupportedCameraRecordingConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SupportedCameraRecordingConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/supported_rtp_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSupportedRTPConfiguration = "116" 5 | 6 | type SupportedRTPConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSupportedRTPConfiguration() *SupportedRTPConfiguration { 11 | char := NewBytes(TypeSupportedRTPConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SupportedRTPConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/supported_video_recording_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSupportedVideoRecordingConfiguration = "206" 5 | 6 | type SupportedVideoRecordingConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSupportedVideoRecordingConfiguration() *SupportedVideoRecordingConfiguration { 11 | char := NewBytes(TypeSupportedVideoRecordingConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SupportedVideoRecordingConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/supported_video_stream_configuration.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeSupportedVideoStreamConfiguration = "114" 5 | 6 | type SupportedVideoStreamConfiguration struct { 7 | *Bytes 8 | } 9 | 10 | func NewSupportedVideoStreamConfiguration() *SupportedVideoStreamConfiguration { 11 | char := NewBytes(TypeSupportedVideoStreamConfiguration) 12 | char.Format = FormatTLV8 13 | char.Perms = []string{PermRead} 14 | 15 | char.SetValue([]byte{}) 16 | 17 | return &SupportedVideoStreamConfiguration{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/swing_mode.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | SwingModeSwingDisabled int = 0 6 | SwingModeSwingEnabled int = 1 7 | ) 8 | 9 | const TypeSwingMode = "B6" 10 | 11 | type SwingMode struct { 12 | *Int 13 | } 14 | 15 | func NewSwingMode() *SwingMode { 16 | char := NewInt(TypeSwingMode) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &SwingMode{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/target_air_purifier_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetAirPurifierStateManual int = 0 6 | TargetAirPurifierStateAuto int = 1 7 | ) 8 | 9 | const TypeTargetAirPurifierState = "A8" 10 | 11 | type TargetAirPurifierState struct { 12 | *Int 13 | } 14 | 15 | func NewTargetAirPurifierState() *TargetAirPurifierState { 16 | char := NewInt(TypeTargetAirPurifierState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &TargetAirPurifierState{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/target_air_quality.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetAirQualityExcellent int = 0 6 | TargetAirQualityGood int = 1 7 | TargetAirQualityFair int = 2 8 | ) 9 | 10 | const TypeTargetAirQuality = "AE" 11 | 12 | type TargetAirQuality struct { 13 | *Int 14 | } 15 | 16 | func NewTargetAirQuality() *TargetAirQuality { 17 | char := NewInt(TypeTargetAirQuality) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermWrite, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &TargetAirQuality{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/target_door_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetDoorStateOpen int = 0 6 | TargetDoorStateClosed int = 1 7 | ) 8 | 9 | const TypeTargetDoorState = "32" 10 | 11 | type TargetDoorState struct { 12 | *Int 13 | } 14 | 15 | func NewTargetDoorState() *TargetDoorState { 16 | char := NewInt(TypeTargetDoorState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &TargetDoorState{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/target_fan_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetFanStateManual int = 0 6 | TargetFanStateAuto int = 1 7 | ) 8 | 9 | const TypeTargetFanState = "BF" 10 | 11 | type TargetFanState struct { 12 | *Int 13 | } 14 | 15 | func NewTargetFanState() *TargetFanState { 16 | char := NewInt(TypeTargetFanState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &TargetFanState{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/target_heater_cooler_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetHeaterCoolerStateAuto int = 0 6 | TargetHeaterCoolerStateHeat int = 1 7 | TargetHeaterCoolerStateCool int = 2 8 | ) 9 | 10 | const TypeTargetHeaterCoolerState = "B2" 11 | 12 | type TargetHeaterCoolerState struct { 13 | *Int 14 | } 15 | 16 | func NewTargetHeaterCoolerState() *TargetHeaterCoolerState { 17 | char := NewInt(TypeTargetHeaterCoolerState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermWrite, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &TargetHeaterCoolerState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/target_heating_cooling_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetHeatingCoolingStateOff int = 0 6 | TargetHeatingCoolingStateHeat int = 1 7 | TargetHeatingCoolingStateCool int = 2 8 | TargetHeatingCoolingStateAuto int = 3 9 | ) 10 | 11 | const TypeTargetHeatingCoolingState = "33" 12 | 13 | type TargetHeatingCoolingState struct { 14 | *Int 15 | } 16 | 17 | func NewTargetHeatingCoolingState() *TargetHeatingCoolingState { 18 | char := NewInt(TypeTargetHeatingCoolingState) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermWrite, PermEvents} 21 | 22 | char.SetValue(0) 23 | 24 | return &TargetHeatingCoolingState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/target_horizontal_tilt_angle.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTargetHorizontalTiltAngle = "7B" 5 | 6 | type TargetHorizontalTiltAngle struct { 7 | *Int 8 | } 9 | 10 | func NewTargetHorizontalTiltAngle() *TargetHorizontalTiltAngle { 11 | char := NewInt(TypeTargetHorizontalTiltAngle) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(-90) 15 | char.SetMaxValue(90) 16 | char.SetStepValue(1) 17 | char.SetValue(-90) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &TargetHorizontalTiltAngle{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/target_humidifier_dehumidifier_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetHumidifierDehumidifierStateHumidifierOrDehumidifier int = 0 6 | TargetHumidifierDehumidifierStateHumidifier int = 1 7 | TargetHumidifierDehumidifierStateDehumidifier int = 2 8 | ) 9 | 10 | const TypeTargetHumidifierDehumidifierState = "B4" 11 | 12 | type TargetHumidifierDehumidifierState struct { 13 | *Int 14 | } 15 | 16 | func NewTargetHumidifierDehumidifierState() *TargetHumidifierDehumidifierState { 17 | char := NewInt(TypeTargetHumidifierDehumidifierState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermWrite, PermEvents} 20 | 21 | char.SetValue(0) 22 | 23 | return &TargetHumidifierDehumidifierState{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/target_media_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetMediaStatePlay int = 0 6 | TargetMediaStatePause int = 1 7 | TargetMediaStateStop int = 2 8 | ) 9 | 10 | const TypeTargetMediaState = "137" 11 | 12 | type TargetMediaState struct { 13 | *Int 14 | } 15 | 16 | func NewTargetMediaState() *TargetMediaState { 17 | char := NewInt(TypeTargetMediaState) 18 | char.Format = FormatUInt8 19 | char.Perms = []string{PermRead, PermWrite, PermEvents} 20 | char.SetMinValue(0) 21 | char.SetMaxValue(2) 22 | char.SetStepValue(1) 23 | char.SetValue(0) 24 | 25 | return &TargetMediaState{char} 26 | } 27 | -------------------------------------------------------------------------------- /characteristic/target_position.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTargetPosition = "7C" 5 | 6 | type TargetPosition struct { 7 | *Int 8 | } 9 | 10 | func NewTargetPosition() *TargetPosition { 11 | char := NewInt(TypeTargetPosition) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &TargetPosition{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/target_relative_humidity.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTargetRelativeHumidity = "34" 5 | 6 | type TargetRelativeHumidity struct { 7 | *Float 8 | } 9 | 10 | func NewTargetRelativeHumidity() *TargetRelativeHumidity { 11 | char := NewFloat(TypeTargetRelativeHumidity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &TargetRelativeHumidity{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/target_slat_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetSlatStateManual int = 0 6 | TargetSlatStateAuto int = 1 7 | ) 8 | 9 | const TypeTargetSlatState = "BE" 10 | 11 | type TargetSlatState struct { 12 | *Int 13 | } 14 | 15 | func NewTargetSlatState() *TargetSlatState { 16 | char := NewInt(TypeTargetSlatState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &TargetSlatState{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/target_temperature.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTargetTemperature = "35" 5 | 6 | type TargetTemperature struct { 7 | *Float 8 | } 9 | 10 | func NewTargetTemperature() *TargetTemperature { 11 | char := NewFloat(TypeTargetTemperature) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(10) 15 | char.SetMaxValue(38) 16 | char.SetStepValue(0.1) 17 | char.SetValue(10) 18 | char.Unit = UnitCelsius 19 | 20 | return &TargetTemperature{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/target_tilt_angle.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTargetTiltAngle = "C2" 5 | 6 | type TargetTiltAngle struct { 7 | *Int 8 | } 9 | 10 | func NewTargetTiltAngle() *TargetTiltAngle { 11 | char := NewInt(TypeTargetTiltAngle) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(-90) 15 | char.SetMaxValue(90) 16 | char.SetStepValue(1) 17 | char.SetValue(-90) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &TargetTiltAngle{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/target_vertical_tilt_angle.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTargetVerticalTiltAngle = "7D" 5 | 6 | type TargetVerticalTiltAngle struct { 7 | *Int 8 | } 9 | 10 | func NewTargetVerticalTiltAngle() *TargetVerticalTiltAngle { 11 | char := NewInt(TypeTargetVerticalTiltAngle) 12 | char.Format = FormatInt32 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(-90) 15 | char.SetMaxValue(90) 16 | char.SetStepValue(1) 17 | char.SetValue(-90) 18 | char.Unit = UnitArcDegrees 19 | 20 | return &TargetVerticalTiltAngle{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/target_visibility_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TargetVisibilityStateShown int = 0 6 | TargetVisibilityStateHidden int = 1 7 | ) 8 | 9 | const TypeTargetVisibilityState = "134" 10 | 11 | type TargetVisibilityState struct { 12 | *Int 13 | } 14 | 15 | func NewTargetVisibilityState() *TargetVisibilityState { 16 | char := NewInt(TypeTargetVisibilityState) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | char.SetMinValue(0) 20 | char.SetMaxValue(2) 21 | char.SetStepValue(1) 22 | char.SetValue(0) 23 | 24 | return &TargetVisibilityState{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/temperature_display_units.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | TemperatureDisplayUnitsCelsius int = 0 6 | TemperatureDisplayUnitsFahrenheit int = 1 7 | ) 8 | 9 | const TypeTemperatureDisplayUnits = "36" 10 | 11 | type TemperatureDisplayUnits struct { 12 | *Int 13 | } 14 | 15 | func NewTemperatureDisplayUnits() *TemperatureDisplayUnits { 16 | char := NewInt(TypeTemperatureDisplayUnits) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermRead, PermWrite, PermEvents} 19 | 20 | char.SetValue(0) 21 | 22 | return &TemperatureDisplayUnits{char} 23 | } 24 | -------------------------------------------------------------------------------- /characteristic/test_conn.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | import ( 4 | "net" 5 | "time" 6 | ) 7 | 8 | var TestConn net.Conn = &fakeConn{} 9 | 10 | type fakeConn struct { 11 | } 12 | 13 | func (f *fakeConn) Read(b []byte) (n int, err error) { 14 | return 0, nil 15 | } 16 | 17 | func (f *fakeConn) Write(b []byte) (n int, err error) { 18 | return 0, nil 19 | } 20 | 21 | func (f *fakeConn) Close() error { 22 | return nil 23 | } 24 | 25 | func (f *fakeConn) LocalAddr() net.Addr { 26 | return nil 27 | } 28 | 29 | func (f *fakeConn) RemoteAddr() net.Addr { 30 | return nil 31 | } 32 | 33 | func (f *fakeConn) SetDeadline(t time.Time) error { 34 | return nil 35 | } 36 | 37 | func (f *fakeConn) SetReadDeadline(t time.Time) error { 38 | return nil 39 | } 40 | 41 | func (f *fakeConn) SetWriteDeadline(t time.Time) error { 42 | return nil 43 | } 44 | -------------------------------------------------------------------------------- /characteristic/time_update.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTimeUpdate = "9A" 5 | 6 | type TimeUpdate struct { 7 | *Bool 8 | } 9 | 10 | func NewTimeUpdate() *TimeUpdate { 11 | char := NewBool(TypeTimeUpdate) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &TimeUpdate{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/tunnel_connection_timeout.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTunnelConnectionTimeout = "61" 5 | 6 | type TunnelConnectionTimeout struct { 7 | *Int 8 | } 9 | 10 | func NewTunnelConnectionTimeout() *TunnelConnectionTimeout { 11 | char := NewInt(TypeTunnelConnectionTimeout) 12 | char.Format = FormatUInt32 13 | char.Perms = []string{PermWrite, PermRead, PermEvents} 14 | 15 | char.SetValue(0) 16 | 17 | return &TunnelConnectionTimeout{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/tunneled_accessory_advertising.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTunneledAccessoryAdvertising = "60" 5 | 6 | type TunneledAccessoryAdvertising struct { 7 | *Bool 8 | } 9 | 10 | func NewTunneledAccessoryAdvertising() *TunneledAccessoryAdvertising { 11 | char := NewBool(TypeTunneledAccessoryAdvertising) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermWrite, PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &TunneledAccessoryAdvertising{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/tunneled_accessory_connected.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTunneledAccessoryConnected = "59" 5 | 6 | type TunneledAccessoryConnected struct { 7 | *Bool 8 | } 9 | 10 | func NewTunneledAccessoryConnected() *TunneledAccessoryConnected { 11 | char := NewBool(TypeTunneledAccessoryConnected) 12 | char.Format = FormatBool 13 | char.Perms = []string{PermWrite, PermRead, PermEvents} 14 | 15 | char.SetValue(false) 16 | 17 | return &TunneledAccessoryConnected{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/tunneled_accessory_state_number.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeTunneledAccessoryStateNumber = "58" 5 | 6 | type TunneledAccessoryStateNumber struct { 7 | *Float 8 | } 9 | 10 | func NewTunneledAccessoryStateNumber() *TunneledAccessoryStateNumber { 11 | char := NewFloat(TypeTunneledAccessoryStateNumber) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue(0) 16 | 17 | return &TunneledAccessoryStateNumber{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/valve_type.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | ValveTypeGenericValve int = 0 6 | ValveTypeIrrigation int = 1 7 | ValveTypeShowerHead int = 2 8 | ValveTypeWaterFaucet int = 3 9 | ) 10 | 11 | const TypeValveType = "D5" 12 | 13 | type ValveType struct { 14 | *Int 15 | } 16 | 17 | func NewValveType() *ValveType { 18 | char := NewInt(TypeValveType) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermEvents} 21 | 22 | char.SetValue(0) 23 | 24 | return &ValveType{char} 25 | } 26 | -------------------------------------------------------------------------------- /characteristic/version.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeVersion = "37" 5 | 6 | type Version struct { 7 | *String 8 | } 9 | 10 | func NewVersion() *Version { 11 | char := NewString(TypeVersion) 12 | char.Format = FormatString 13 | char.Perms = []string{PermRead, PermEvents} 14 | 15 | char.SetValue("") 16 | 17 | return &Version{char} 18 | } 19 | -------------------------------------------------------------------------------- /characteristic/voc_density.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeVOCDensity = "C8" 5 | 6 | type VOCDensity struct { 7 | *Float 8 | } 9 | 10 | func NewVOCDensity() *VOCDensity { 11 | char := NewFloat(TypeVOCDensity) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(1000) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | 19 | return &VOCDensity{char} 20 | } 21 | -------------------------------------------------------------------------------- /characteristic/volume.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeVolume = "119" 5 | 6 | type Volume struct { 7 | *Int 8 | } 9 | 10 | func NewVolume() *Volume { 11 | char := NewInt(TypeVolume) 12 | char.Format = FormatUInt8 13 | char.Perms = []string{PermRead, PermWrite, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | char.SetStepValue(1) 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &Volume{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/volume_control_type.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | VolumeControlTypeNone int = 0 6 | VolumeControlTypeRelative int = 1 7 | VolumeControlTypeRelativeWithCurrent int = 2 8 | VolumeControlTypeAbsolute int = 3 9 | ) 10 | 11 | const TypeVolumeControlType = "E9" 12 | 13 | type VolumeControlType struct { 14 | *Int 15 | } 16 | 17 | func NewVolumeControlType() *VolumeControlType { 18 | char := NewInt(TypeVolumeControlType) 19 | char.Format = FormatUInt8 20 | char.Perms = []string{PermRead, PermEvents} 21 | char.SetMinValue(0) 22 | char.SetMaxValue(3) 23 | char.SetStepValue(1) 24 | char.SetValue(0) 25 | 26 | return &VolumeControlType{char} 27 | } 28 | -------------------------------------------------------------------------------- /characteristic/volume_selector.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const ( 5 | VolumeSelectorIncrement int = 0 6 | VolumeSelectorDecrement int = 1 7 | ) 8 | 9 | const TypeVolumeSelector = "EA" 10 | 11 | type VolumeSelector struct { 12 | *Int 13 | } 14 | 15 | func NewVolumeSelector() *VolumeSelector { 16 | char := NewInt(TypeVolumeSelector) 17 | char.Format = FormatUInt8 18 | char.Perms = []string{PermWrite} 19 | char.SetMinValue(0) 20 | char.SetMaxValue(1) 21 | char.SetStepValue(1) 22 | 23 | return &VolumeSelector{char} 24 | } 25 | -------------------------------------------------------------------------------- /characteristic/water_level.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package characteristic 3 | 4 | const TypeWaterLevel = "B5" 5 | 6 | type WaterLevel struct { 7 | *Float 8 | } 9 | 10 | func NewWaterLevel() *WaterLevel { 11 | char := NewFloat(TypeWaterLevel) 12 | char.Format = FormatFloat 13 | char.Perms = []string{PermRead, PermEvents} 14 | char.SetMinValue(0) 15 | char.SetMaxValue(100) 16 | 17 | char.SetValue(0) 18 | char.Unit = UnitPercentage 19 | 20 | return &WaterLevel{char} 21 | } 22 | -------------------------------------------------------------------------------- /characteristic/wifi_capabilities.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | const TypeWifiCapabilities = "22C" 4 | 5 | type WifiCapabilities = struct { 6 | *Int 7 | } 8 | 9 | func NewWifiCapabilities() *WifiCapabilities { 10 | char := NewInt(TypeWifiCapabilities) 11 | char.Format = FormatUInt32 12 | char.Perms = []string{PermRead} 13 | 14 | char.SetValue(1) 15 | return &WifiCapabilities{char} 16 | } 17 | -------------------------------------------------------------------------------- /characteristic/wifi_configuration_control.go: -------------------------------------------------------------------------------- 1 | package characteristic 2 | 3 | const TypeWifiConfigurationControl = "22D" 4 | 5 | type WifiConfigurationControl = struct { 6 | *Bytes 7 | } 8 | 9 | func NewWifiConfigurationControl() *WifiConfigurationControl { 10 | char := NewBytes(TypeWifiCapabilities) 11 | char.Format = FormatTLV8 12 | char.Perms = []string{PermRead, PermWrite, PermEvents} 13 | 14 | return &WifiConfigurationControl{char} 15 | } 16 | -------------------------------------------------------------------------------- /cmd/swift_decl.go: -------------------------------------------------------------------------------- 1 | // +build ignore 2 | 3 | // Creates swift code for all HomeKit service and characteristic types and logs 4 | // that to the console. 5 | 6 | package main 7 | 8 | import ( 9 | "encoding/json" 10 | "github.com/brutella/hc/gen" 11 | "github.com/brutella/hc/gen/swift" 12 | "io/ioutil" 13 | "log" 14 | "os" 15 | "path/filepath" 16 | ) 17 | 18 | var LibPath = os.ExpandEnv("$GOPATH/src/github.com/brutella/hc") 19 | var GenPath = filepath.Join(LibPath, "gen") 20 | var MetadataPath = filepath.Join(GenPath, "metadata.json") 21 | 22 | func main() { 23 | 24 | log.Println("Import data from", MetadataPath) 25 | 26 | // Open metadata file 27 | f, err := os.Open(MetadataPath) 28 | if err != nil { 29 | log.Fatal(err) 30 | } 31 | 32 | // Read content 33 | b, err := ioutil.ReadAll(f) 34 | if err != nil { 35 | log.Fatal(err) 36 | } 37 | 38 | // Import json 39 | metadata := gen.Metadata{} 40 | err = json.Unmarshal(b, &metadata) 41 | if err != nil { 42 | log.Fatal(err) 43 | } 44 | 45 | if b, err := swift.CharacteristicEnumDecl(metadata); err != nil { 46 | log.Fatal(err) 47 | } else { 48 | log.Println(string(b)) 49 | } 50 | 51 | if b, err := swift.ServiceEnumDecl(metadata); err != nil { 52 | log.Fatal(err) 53 | } else { 54 | log.Println(string(b)) 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /crypto/cryptographer.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | // Encrypter encrypts bytes. 8 | type Encrypter interface { 9 | Encrypt(r io.Reader) (io.Reader, error) 10 | } 11 | 12 | // Decrypter decrypts bytes. 13 | type Decrypter interface { 14 | Decrypt(r io.Reader) (io.Reader, error) 15 | } 16 | 17 | // A Cryptographer is a De- and Encrypter. 18 | type Cryptographer interface { 19 | Encrypter 20 | Decrypter 21 | } 22 | -------------------------------------------------------------------------------- /crypto/curve25519/curve25519.go: -------------------------------------------------------------------------------- 1 | package curve25519 2 | 3 | import ( 4 | "crypto/rand" 5 | "golang.org/x/crypto/curve25519" 6 | ) 7 | 8 | const ( 9 | keySize = 32 10 | ) 11 | 12 | // GeneratePrivateKey returns random bytes. 13 | func GeneratePrivateKey() [keySize]byte { 14 | var b [keySize]byte 15 | rand.Read(b[:]) 16 | 17 | return b 18 | } 19 | 20 | // PublicKey returns a Curve25519 public key derived from privateKey. 21 | func PublicKey(privateKey [keySize]byte) [keySize]byte { 22 | var k [keySize]byte 23 | curve25519.ScalarBaseMult(&k, &privateKey) 24 | 25 | return k 26 | } 27 | 28 | // SharedSecret returns a Curve25519 shared secret derived from privateKey and otherPublicKey. 29 | func SharedSecret(privateKey, otherPublicKey [keySize]byte) [keySize]byte { 30 | var k [keySize]byte 31 | curve25519.ScalarMult(&k, &privateKey, &otherPublicKey) 32 | 33 | return k 34 | } 35 | -------------------------------------------------------------------------------- /crypto/doc.go: -------------------------------------------------------------------------------- 1 | // Package crypto provides the crypthographic algorithm used in the HAP protocol. 2 | package crypto 3 | -------------------------------------------------------------------------------- /crypto/ed25519.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "bytes" 5 | "crypto/ed25519" 6 | "fmt" 7 | ) 8 | 9 | // ValidateED25519Signature return true when the ED25519 signature is a valid signature of the data based on the key, otherwise false. 10 | func ValidateED25519Signature(key, data, signature []byte) bool { 11 | if len(key) != ed25519.PublicKeySize || len(signature) != ed25519.SignatureSize { 12 | return false 13 | } 14 | 15 | return ed25519.Verify(ed25519.PublicKey(key), data, signature) 16 | } 17 | 18 | // ED25519Signature returns the ED25519 signature of data using the key. 19 | func ED25519Signature(key, data []byte) ([]byte, error) { 20 | if len(key) != ed25519.PrivateKeySize { 21 | return nil, fmt.Errorf("Invalid size of key (%v)", len(key)) 22 | } 23 | 24 | signature := ed25519.Sign(ed25519.PrivateKey(key), data) 25 | 26 | return signature[:], nil 27 | } 28 | 29 | // ED25519GenerateKey return a public and private ED25519 key pair from a string. 30 | func ED25519GenerateKey(str string) ([]byte /* public */, []byte /* private */, error) { 31 | b := bytes.NewBuffer([]byte(str)) 32 | if len(str) < 32 { 33 | zeros := make([]byte, 32-len(str)) 34 | b.Write(zeros) 35 | } 36 | 37 | public, private, err := ed25519.GenerateKey(bytes.NewReader(b.Bytes())) 38 | 39 | return public[:], private[:], err 40 | } 41 | -------------------------------------------------------------------------------- /crypto/hkdf/hkdf.go: -------------------------------------------------------------------------------- 1 | package hkdf 2 | 3 | import ( 4 | "crypto/sha512" 5 | "golang.org/x/crypto/hkdf" 6 | "io" 7 | ) 8 | 9 | // Sha512 returns a 256-bit key 10 | func Sha512(master, salt, info []byte) ([32]byte, error) { 11 | hash := sha512.New 12 | hkdf := hkdf.New(hash, master, salt, info) 13 | 14 | key := make([]byte, 32) // 256 bit 15 | _, err := io.ReadFull(hkdf, key) 16 | 17 | var result [32]byte 18 | copy(result[:], key) 19 | 20 | return result, err 21 | } 22 | -------------------------------------------------------------------------------- /crypto/packet.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | const ( 8 | // PacketLengthMax is the max length of encrypted packets 9 | PacketLengthMax = 0x400 10 | ) 11 | 12 | type packet struct { 13 | length int 14 | value []byte 15 | } 16 | 17 | // packetsWithSizeFromBytes returns lv (tlv without t(ype)) packets 18 | func packetsWithSizeFromBytes(length int, r io.Reader) []packet { 19 | var packets []packet 20 | for { 21 | var value = make([]byte, length) 22 | n, err := r.Read(value) 23 | if n == 0 { 24 | break 25 | } 26 | 27 | if n > length { 28 | panic("Invalid length") 29 | } 30 | 31 | p := packet{length: n, value: value[:n]} 32 | packets = append(packets, p) 33 | 34 | if n < length || err == io.EOF { 35 | break 36 | } 37 | } 38 | 39 | return packets 40 | } 41 | 42 | // packetsFromBytes returns packets with length PacketLengthMax 43 | func packetsFromBytes(r io.Reader) []packet { 44 | return packetsWithSizeFromBytes(PacketLengthMax, r) 45 | } 46 | -------------------------------------------------------------------------------- /crypto/packet_test.go: -------------------------------------------------------------------------------- 1 | package crypto 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | func TestPacketFromBytes(t *testing.T) { 9 | b := bytes.NewBuffer([]byte{0x01, 0x02, 0x03}) 10 | packets := packetsFromBytes(b) 11 | 12 | if x := len(packets); x != 1 { 13 | t.Fatal(x) 14 | } 15 | 16 | p := packets[0] 17 | 18 | if x := p.length; x != 3 { 19 | t.Fatal(x) 20 | } 21 | if x := len(p.value); x != p.length { 22 | t.Fatal(x) 23 | } 24 | } 25 | 26 | func TestMultiplePacketFromBytes(t *testing.T) { 27 | b := bytes.NewBuffer([]byte{0x01, 0x02, 0x03, 0x04, 0x05}) 28 | p := packetsWithSizeFromBytes(3, b) 29 | 30 | if x := len(p); x != 2 { 31 | t.Fatal(x) 32 | } 33 | if x := p[0].length; x != 3 { 34 | t.Fatal(x) 35 | } 36 | if x := p[1].length; x != 2 { 37 | t.Fatal(x) 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /db/doc.go: -------------------------------------------------------------------------------- 1 | // Package db implements persistent storage. 2 | package db 3 | -------------------------------------------------------------------------------- /db/entity.go: -------------------------------------------------------------------------------- 1 | package db 2 | 3 | import ( 4 | "github.com/brutella/hc/crypto" 5 | "github.com/brutella/hc/util" 6 | ) 7 | 8 | type Entity struct { 9 | Name string 10 | PublicKey []byte 11 | PrivateKey []byte 12 | } 13 | 14 | // NewRandomEntityWithName returns an entity with a random private and public keys 15 | func NewRandomEntityWithName(name string) (e Entity, err error) { 16 | var public []byte 17 | var private []byte 18 | 19 | public, private, err = generateKeyPairs() 20 | if err == nil && len(public) > 0 && len(private) > 0 { 21 | e = NewEntity(name, public, private) 22 | } 23 | 24 | return 25 | } 26 | 27 | // NewEntity returns a entity with a name, public and private key. 28 | func NewEntity(name string, publicKey, privateKey []byte) Entity { 29 | return Entity{Name: name, PublicKey: publicKey, PrivateKey: privateKey} 30 | } 31 | 32 | // generateKeyPairs generates random public and private key pairs 33 | func generateKeyPairs() ([]byte, []byte, error) { 34 | str := util.RandomHexString() 35 | public, private, err := crypto.ED25519GenerateKey(str) 36 | return public, private, err 37 | } 38 | -------------------------------------------------------------------------------- /doc.go: -------------------------------------------------------------------------------- 1 | // Package hc provides implementation of an IP transport for HomeKit accessories. 2 | // 3 | // import ( 4 | // "github.com/brutella/hc" 5 | // "github.com/brutella/hc/accessory" 6 | // ) 7 | // 8 | // acc := accessory.NewSwitch(...) 9 | // config := hc.Config{Pin: "00102003"} 10 | // t, err := hc.NewIPTransport(config, acc.Accessory) 11 | // ... 12 | // t.Start() 13 | package hc 14 | -------------------------------------------------------------------------------- /event/constant.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | // DevicePaired is emitted when transport paired with a device (e.g. iOS client successfully paired with the accessory) 4 | type DevicePaired struct{} 5 | 6 | // DeviceUnpaired is emitted when pairing with a device is removed (e.g. iOS client removed the accessory from HomeKit) 7 | type DeviceUnpaired struct{} 8 | -------------------------------------------------------------------------------- /event/event_emitter.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | // Emitter emits events to listeners 4 | type Emitter interface { 5 | 6 | // Emit emits the event to all listeners 7 | Emit(ev interface{}) 8 | 9 | // AddListener adds a listener to the event stream 10 | AddListener(l EventListener) 11 | } 12 | 13 | type eventEmitter struct { 14 | ls []EventListener 15 | } 16 | 17 | // NewEmitter returns a new event emitter 18 | func NewEmitter() Emitter { 19 | return &eventEmitter{ 20 | ls: make([]EventListener, 0), 21 | } 22 | } 23 | 24 | func (e *eventEmitter) Emit(ev interface{}) { 25 | for _, l := range e.ls { 26 | l.Handle(ev) 27 | } 28 | } 29 | 30 | func (e *eventEmitter) AddListener(l EventListener) { 31 | e.ls = append(e.ls, l) 32 | } 33 | -------------------------------------------------------------------------------- /event/event_emitter_test.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | type testListener struct { 8 | last interface{} 9 | } 10 | 11 | func (l *testListener) Handle(e interface{}) { 12 | l.last = e 13 | } 14 | 15 | func TestEmitter(t *testing.T) { 16 | e := NewEmitter() 17 | 18 | l := &testListener{} 19 | e.AddListener(l) 20 | 21 | e.Emit(10) 22 | 23 | if x := l.last; x != 10 { 24 | t.Fatal(x) 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /event/event_listener.go: -------------------------------------------------------------------------------- 1 | package event 2 | 3 | // EventListener handles events 4 | type EventListener interface { 5 | Handle(e interface{}) 6 | } 7 | -------------------------------------------------------------------------------- /gen/golang/path.go: -------------------------------------------------------------------------------- 1 | package golang 2 | 3 | import ( 4 | "github.com/brutella/hc/gen" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | var ( 10 | libPath = os.ExpandEnv("$GOPATH/src/github.com/brutella/hc") 11 | ServiceLocalDir = filepath.Join(libPath, "service") 12 | CharacteristicLocalDir = filepath.Join(libPath, "characteristic") 13 | ServiceDir = "service" 14 | CharacteristicDir = "characteristic" 15 | ) 16 | 17 | // CharacteristicLocalFilePath returns the filepath to a characteristic 18 | func CharacteristicLocalFilePath(char *gen.CharacteristicMetadata) string { 19 | return filepath.Join(CharacteristicLocalDir, CharacteristicFileName(char)) 20 | } 21 | 22 | // CharacteristicRelativeFilePath returns the relative filepath to a characteristic 23 | func CharacteristicRelativeFilePath(char *gen.CharacteristicMetadata) string { 24 | return filepath.Join(CharacteristicDir, CharacteristicFileName(char)) 25 | } 26 | 27 | // ServiceLocalFilePath returns the filepath to a service 28 | func ServiceLocalFilePath(sv *gen.ServiceMetadata) string { 29 | return filepath.Join(ServiceLocalDir, ServiceFileName(sv)) 30 | } 31 | 32 | // ServiceRelativeFilePath returns the relative filepath to a service 33 | func ServiceRelativeFilePath(sv *gen.ServiceMetadata) string { 34 | return filepath.Join(ServiceDir, ServiceFileName(sv)) 35 | } 36 | -------------------------------------------------------------------------------- /gen/markdown/category.go: -------------------------------------------------------------------------------- 1 | package markdown 2 | 3 | import ( 4 | "bytes" 5 | "github.com/brutella/hc/gen" 6 | "text/template" 7 | ) 8 | 9 | // CatsStructTemplate is template for a CategoryMetadata struct. 10 | const CategoriesTemplate = `| Accessory | Category | 11 | | --- | --- |{{range .Categories}} 12 | | {{.Name}} | {{ .Category}} | {{end}}` 13 | 14 | // CategoriesGoCode returns the go code for a categories file 15 | func CategoriesCode(m *gen.Metadata) ([]byte, error) { 16 | var err error 17 | var buf bytes.Buffer 18 | 19 | t := template.New("Test Template") 20 | t, err = t.Parse(CategoriesTemplate) 21 | t.Execute(&buf, m) 22 | 23 | return buf.Bytes(), err 24 | } 25 | -------------------------------------------------------------------------------- /gen/markdown/service.go: -------------------------------------------------------------------------------- 1 | package markdown 2 | 3 | import ( 4 | "bytes" 5 | "github.com/brutella/hc/gen" 6 | "github.com/brutella/hc/gen/golang" 7 | "text/template" 8 | ) 9 | 10 | const ServicesTemplate = `| Service | Characteristics | ID 11 | | --- | --- | --- | 12 | {{range .Svcs}}| {{.Name}} | {{range $idx, $ch := .Chars}}{{ if $idx }}
{{ end }}{{ $ch.Name }}{{end}}{{range $idx, $ch := .Optional}}
{{ $ch.Name }} Optional{{end}} | {{ .TypeValue }} | 13 | {{end}}` 14 | 15 | type Services struct { 16 | Svcs []*golang.Service 17 | } 18 | 19 | func ServicesCode(m *gen.Metadata) ([]byte, error) { 20 | var err error 21 | var buf bytes.Buffer 22 | 23 | var svcs []*golang.Service 24 | for _, svc := range m.Services { 25 | svcs = append(svcs, golang.ServiceDecl(svc, m.Characteristics)) 26 | } 27 | 28 | data := Services{svcs} 29 | t := template.New("Test Template") 30 | t, err = t.Parse(ServicesTemplate) 31 | t.Execute(&buf, data) 32 | 33 | return buf.Bytes(), err 34 | } 35 | -------------------------------------------------------------------------------- /gen/metadata.go: -------------------------------------------------------------------------------- 1 | package gen 2 | 3 | // Metadata represents the data in a HomeKit metadata file 4 | type Metadata struct { 5 | Categories []*CategoryMetadata 6 | Characteristics []*CharacteristicMetadata 7 | Services []*ServiceMetadata 8 | } 9 | 10 | // CharacteristicMetadata represents a characteristic metadata entry 11 | type CharacteristicMetadata struct { 12 | Constraints interface{} `json:Constraints,omitempty` 13 | Format string 14 | Name string 15 | Permissions []string 16 | Properties []string `json:Properties,omitempty` 17 | UUID string 18 | Unit string `json:Unit,omitempty` 19 | } 20 | 21 | // ServiceMetadata represents a service metadata entry 22 | type ServiceMetadata struct { 23 | RequiredCharacteristics []string 24 | OptionalCharacteristics []string 25 | Name string 26 | UUID string 27 | } 28 | 29 | // CategoryMetadata represents an accessory category metadata entry 30 | type CategoryMetadata struct { 31 | Name string 32 | Category int 33 | } 34 | -------------------------------------------------------------------------------- /gen/swift/enum.go: -------------------------------------------------------------------------------- 1 | package swift 2 | 3 | const EnumTemplate = `enum {{.Name}}{{if .HasSuper}}: {{.Super}}{{end}} { 4 | {{range .Cases}}case {{.Name}} = {{.Value}}{{if .HasComment}} // {{.Comment}}{{end}} 5 | {{end}} 6 | }` 7 | 8 | type Enum struct { 9 | Name string 10 | Super string 11 | Cases []*Case 12 | } 13 | 14 | func (e *Enum) HasSuper() bool { 15 | return len(e.Super) > 0 16 | } 17 | 18 | type Case struct { 19 | Name string 20 | Value string 21 | Comment string 22 | } 23 | 24 | func (c *Case) HasComment() bool { 25 | return len(c.Comment) > 0 26 | } 27 | -------------------------------------------------------------------------------- /gen/swift/service.go: -------------------------------------------------------------------------------- 1 | package swift 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "github.com/brutella/hc/gen" 7 | "text/template" 8 | ) 9 | 10 | func ServiceEnumDecl(metadata gen.Metadata) ([]byte, error) { 11 | var err error 12 | var buf bytes.Buffer 13 | 14 | enum := &Enum{ 15 | Name: "ServiceType", 16 | Super: "String", 17 | Cases: []*Case{}, 18 | } 19 | 20 | for _, svc := range metadata.Services { 21 | c := &Case{ 22 | Name: camelCased(svc.Name), 23 | Value: fmt.Sprintf(`"%s"`, svc.UUID), 24 | } 25 | enum.Cases = append(enum.Cases, c) 26 | } 27 | 28 | t := template.New("Test Template") 29 | 30 | t, err = t.Parse(EnumTemplate) 31 | t.Execute(&buf, enum) 32 | 33 | return buf.Bytes(), err 34 | } 35 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/brutella/hc 2 | 3 | require ( 4 | github.com/brutella/dnssd v1.2.1 5 | github.com/miekg/dns v1.1.4 // indirect 6 | github.com/tadglines/go-pkgs v0.0.0-20140924210655-1f86682992f1 7 | github.com/xiam/to v0.0.0-20191116183551-8328998fc0ed 8 | golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad 9 | golang.org/x/text v0.3.3 10 | ) 11 | 12 | go 1.13 13 | -------------------------------------------------------------------------------- /hap/chunked_writer.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | type chunkedWriter struct { 8 | wr io.Writer 9 | chunk int 10 | } 11 | 12 | // NewChunkedWriter returns a writer which writes bytes in chunkes of specified size. 13 | func NewChunkedWriter(wr io.Writer, chunk int) io.Writer { 14 | return &chunkedWriter{wr, chunk} 15 | } 16 | 17 | func (w *chunkedWriter) Write(p []byte) (int, error) { 18 | var max = len(p) 19 | var nn int 20 | var end int 21 | for nn < max { 22 | end = nn + w.chunk 23 | if end > max { 24 | end = max 25 | } 26 | n, err := w.wr.Write(p[nn:end]) 27 | if err != nil { 28 | return nn, err 29 | } 30 | nn += n 31 | } 32 | 33 | return nn, nil 34 | } 35 | -------------------------------------------------------------------------------- /hap/chunked_writer_test.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | import ( 4 | "bytes" 5 | "testing" 6 | ) 7 | 8 | func TestChunkedWriter(t *testing.T) { 9 | var b bytes.Buffer 10 | wr := NewChunkedWriter(&b, 2) 11 | n, err := wr.Write([]byte("Hello World")) 12 | if err != nil { 13 | t.Fatal(err) 14 | } 15 | if is, want := n, 11; is != want { 16 | t.Fatalf("is=%v want=%v", is, want) 17 | } 18 | if is, want := string(b.Bytes()), "Hello World"; is != want { 19 | t.Fatalf("is=%v want=%v", is, want) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /hap/constants.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | const ( 4 | // MethodGET is the HTTP Get method 5 | MethodGET = "GET" 6 | 7 | // MethodPOST is the HTTP Post method 8 | MethodPOST = "POST" 9 | 10 | // MethodPUT is the HTTP Put method 11 | MethodPUT = "PUT" 12 | 13 | // MethodDEL is the HTTP Delete method 14 | MethodDEL = "DEL" 15 | ) 16 | 17 | const ( 18 | StatusSuccess = 0 19 | StatusInsufficientPrivileges = -70401 20 | StatusServiceCommunicationFailure = -70402 21 | StatusResourceBusy = -70403 22 | StatusReadOnlyCharacteristic = -70404 23 | StatusWriteOnlyCharacteristic = -70405 24 | StatusNotificationNotSupported = -70406 25 | StatusOutOfResource = -70407 26 | StatusOperationTimedOut = -70408 27 | StatusResourceDoesNotExist = -70409 28 | StatusInvalidValueInRequest = -70410 29 | ) 30 | 31 | const ( 32 | // HTTPContentTypePairingTLV8 is the HTTP content type for pairing 33 | HTTPContentTypePairingTLV8 = "application/pairing+tlv8" 34 | 35 | // HTTPContentTypeHAPJson is the HTTP content type for json data 36 | HTTPContentTypeHAPJson = "application/hap+json" 37 | ) 38 | -------------------------------------------------------------------------------- /hap/data/characteristics.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | // Characteristics implements json of format 4 | // 5 | // { 6 | // "characteristics": [ 7 | // ... 8 | // ] 9 | // } 10 | type Characteristics struct { 11 | Characteristics []Characteristic `json:"characteristics"` 12 | } 13 | 14 | // Characteristic implements json of format. 15 | // 16 | // { 17 | // "aid": 0, "iid": 1, "value": 10 [, "status": 0, "ev": true ] 18 | // } 19 | type Characteristic struct { 20 | AccessoryID uint64 `json:"aid"` 21 | CharacteristicID uint64 `json:"iid"` 22 | Value interface{} `json:"value"` 23 | 24 | // Status contains the status code. Should be interpreted as integer. 25 | // The property is omitted if not specified, which makes the payload smaller. 26 | Status interface{} `json:"status,omitempty"` 27 | 28 | // Events contains the events settings for a characteristic. Should be interpreted as boolean. 29 | // The property is omitted if not specified, which makes the payload smaller. 30 | Events interface{} `json:"ev,omitempty"` 31 | } 32 | -------------------------------------------------------------------------------- /hap/data/characteristics_test.go: -------------------------------------------------------------------------------- 1 | package data 2 | 3 | import ( 4 | "github.com/xiam/to" 5 | 6 | "encoding/json" 7 | "reflect" 8 | "testing" 9 | ) 10 | 11 | func TestEventCharacteristicFromJSON(t *testing.T) { 12 | var b = []byte(`{"characteristics":[{"aid":2,"iid":13,"status":1,"ev":true}]}`) 13 | var cs Characteristics 14 | 15 | if err := json.Unmarshal(b, &cs); err != nil { 16 | t.Fatal(err) 17 | } 18 | if x := len(cs.Characteristics); x != 1 { 19 | t.Fatal(x) 20 | } 21 | 22 | c := cs.Characteristics[0] 23 | 24 | if x := c.AccessoryID; x != 2 { 25 | t.Fatal(x) 26 | } 27 | if x := c.CharacteristicID; x != 13 { 28 | t.Fatal(x) 29 | } 30 | 31 | if x, ok := c.Events.(bool); ok { 32 | if !x { 33 | t.Fatalf("want=true is=%v", x) 34 | } 35 | } else { 36 | t.Fatalf("invalid events type %v", reflect.TypeOf(x)) 37 | } 38 | 39 | if x := to.Int64(c.Status); x != 1 { 40 | t.Fatal(x) 41 | } 42 | 43 | if c.Value != nil { 44 | t.Fatalf("want=nil is=%v", c.Value) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /hap/data/doc.go: -------------------------------------------------------------------------------- 1 | // Package data provides structs to map json to objects. 2 | package data 3 | -------------------------------------------------------------------------------- /hap/device.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | import ( 4 | "github.com/brutella/hc/db" 5 | ) 6 | 7 | // Device is a HomeKit device with a name, private and public key. 8 | type Device interface { 9 | // Name returns the username used for pairing 10 | Name() string 11 | 12 | // PrivateKey returns the client private key used for pairing 13 | PrivateKey() []byte 14 | 15 | // PublicKey returns the client public key used for pairing 16 | PublicKey() []byte 17 | } 18 | 19 | type device struct { 20 | entity db.Entity 21 | } 22 | 23 | // NewDevice returns a client for a specific name either loaded from the database 24 | // or newly created. 25 | func NewDevice(name string, database db.Database) (Device, error) { 26 | var e db.Entity 27 | var err error 28 | 29 | if e, err = database.EntityWithName(name); err != nil { 30 | if e, err = db.NewRandomEntityWithName(name); err == nil { 31 | err = database.SaveEntity(e) 32 | } 33 | } 34 | 35 | return &device{e}, err 36 | } 37 | 38 | func (d *device) Name() string { 39 | return d.entity.Name 40 | } 41 | 42 | // PairPrivateKey returns the client private key used for pairing 43 | func (d *device) PrivateKey() []byte { 44 | return d.entity.PrivateKey 45 | } 46 | 47 | // PairPublicKey returns the client public key used for pairing 48 | func (d *device) PublicKey() []byte { 49 | return d.entity.PublicKey 50 | } 51 | -------------------------------------------------------------------------------- /hap/device_test.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | import ( 4 | "github.com/brutella/hc/db" 5 | "os" 6 | "reflect" 7 | "testing" 8 | ) 9 | 10 | func TestNewDevice(t *testing.T) { 11 | var e db.Entity 12 | var client Device 13 | var err error 14 | 15 | database, _ := db.NewDatabase(os.TempDir()) 16 | client, err = NewDevice("Test Client", database) 17 | 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | if x := len(client.PublicKey()); x == 0 { 22 | t.Fatal(x) 23 | } 24 | if x := len(client.PrivateKey()); x == 0 { 25 | t.Fatal(x) 26 | } 27 | 28 | if e, err = database.EntityWithName("Test Client"); err != nil { 29 | t.Fatal(err) 30 | } 31 | 32 | if is, want := e.Name, "Test Client"; is != want { 33 | t.Fatalf("is=%v want=%v", is, want) 34 | } 35 | 36 | if err != nil { 37 | t.Fatal(err) 38 | } 39 | if is, want := e.PublicKey, client.PublicKey(); reflect.DeepEqual(is, want) == false { 40 | t.Fatalf("is=%v want=%v", is, want) 41 | } 42 | if is, want := e.PrivateKey, client.PrivateKey(); reflect.DeepEqual(is, want) == false { 43 | t.Fatalf("is=%v want=%v", is, want) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /hap/doc.go: -------------------------------------------------------------------------------- 1 | // Package hap implements the HomeKit Accessory Protocol to pair and securily communicate 2 | // with a HomeKit client. The server send data over tcp to clients (iOS devices) based on 3 | // a http-like protocol. 4 | // 5 | // Pairing: A client has to know the secret pin to pair with the server. After that 6 | // the encryption keys are negotiated and stored on the server and client side. 7 | // 8 | // Session: Before data is exchanged a new pair of keys is generated. The previously negoiated 9 | // keys are verified before the new keys are generated. 10 | package hap 11 | -------------------------------------------------------------------------------- /hap/endpoint/doc.go: -------------------------------------------------------------------------------- 1 | // Package endpoint implements the HAP endpoints. 2 | package endpoint 3 | -------------------------------------------------------------------------------- /hap/handler.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | import ( 4 | "github.com/brutella/hc/util" 5 | ) 6 | 7 | // A ContainerHandler abstracts request/response communication 8 | type ContainerHandler interface { 9 | Handle(util.Container) (util.Container, error) 10 | } 11 | 12 | // A PairVerifyHandler is a ContainerHandler which negotations a shared key. 13 | type PairVerifyHandler interface { 14 | ContainerHandler 15 | SharedKey() [32]byte 16 | } 17 | -------------------------------------------------------------------------------- /hap/http/accessories.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "github.com/brutella/hc/hap" 5 | "github.com/brutella/hc/log" 6 | 7 | "net/http" 8 | ) 9 | 10 | func (srv *Server) Accessories(w http.ResponseWriter, r *http.Request) { 11 | switch r.Method { 12 | case hap.MethodGET: 13 | log.Debug.Printf("%v GET /accessories", r.RemoteAddr) 14 | 15 | srv.mutex.Lock() 16 | if err := WriteJSON(w, r, srv.container); err != nil { 17 | log.Info.Println(err) 18 | } 19 | srv.mutex.Unlock() 20 | 21 | default: 22 | log.Debug.Println("Cannot handle HTTP method", r.Method) 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /hap/http/doc.go: -------------------------------------------------------------------------------- 1 | // Package http implements a http-like hap server to handle requests and responses. 2 | package http 3 | -------------------------------------------------------------------------------- /hap/http/err.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | // ErrResponse is an error response. 4 | type ErrResponse struct { 5 | Status int `json:status` 6 | } 7 | -------------------------------------------------------------------------------- /hap/http/identify.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "github.com/brutella/hc/log" 5 | 6 | "net/http" 7 | ) 8 | 9 | // TODO respond with 400 if accessory is already paired 10 | // 11 | // HTTP/1.1 400 Bad Request 12 | // Content-Type: application/hap+json 13 | // Content-Length: 14 | // { "status" : -70401 } 15 | func (srv *Server) Identify(w http.ResponseWriter, r *http.Request) { 16 | log.Debug.Printf("%v POST /identify", r.RemoteAddr) 17 | for _, a := range srv.container.Accessories { 18 | a.Identify() 19 | } 20 | w.WriteHeader(http.StatusNoContent) 21 | } 22 | -------------------------------------------------------------------------------- /hap/http/json.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "github.com/brutella/hc/hap" 5 | 6 | "bytes" 7 | "encoding/json" 8 | "io" 9 | "net/http" 10 | ) 11 | 12 | func JSONEncode(v interface{}) (*bytes.Buffer, error) { 13 | buf := &bytes.Buffer{} 14 | enc := json.NewEncoder(buf) 15 | enc.SetEscapeHTML(true) 16 | err := enc.Encode(v) 17 | 18 | return buf, err 19 | } 20 | 21 | func JSONDecode(r io.Reader, v interface{}) error { 22 | return json.NewDecoder(r).Decode(v) 23 | } 24 | 25 | func WriteJSON(w http.ResponseWriter, r *http.Request, v interface{}) error { 26 | buf, err := JSONEncode(v) 27 | if err != nil { 28 | http.Error(w, err.Error(), http.StatusInternalServerError) 29 | return err 30 | } 31 | 32 | wr := hap.NewChunkedWriter(w, 2048) 33 | wr.Write(buf.Bytes()) 34 | 35 | return nil 36 | } 37 | 38 | func ReadJSON(w http.ResponseWriter, r *http.Request, v interface{}) error { 39 | if err := JSONDecode(r.Body, v); err != nil { 40 | return err 41 | } 42 | 43 | return nil 44 | } 45 | -------------------------------------------------------------------------------- /hap/http/listener.go: -------------------------------------------------------------------------------- 1 | package http 2 | 3 | import ( 4 | "github.com/brutella/hc/hap" 5 | 6 | "net" 7 | ) 8 | 9 | func (s *Server) Accept() (con net.Conn, err error) { 10 | con, err = s.listener.AcceptTCP() 11 | if err != nil { 12 | return 13 | } 14 | 15 | hapCon := hap.NewConnection(con, s.context) 16 | 17 | return hapCon, err 18 | } 19 | 20 | func (s *Server) Close() error { 21 | return s.listener.Close() 22 | } 23 | 24 | func (s *Server) Addr() net.Addr { 25 | return s.listener.Addr() 26 | } 27 | -------------------------------------------------------------------------------- /hap/pair/admin.go: -------------------------------------------------------------------------------- 1 | package pair 2 | 3 | const ( 4 | NonAdminPerm = 0x00 5 | AdminPerm = 0x01 6 | ) 7 | -------------------------------------------------------------------------------- /hap/pair/doc.go: -------------------------------------------------------------------------------- 1 | // Package pair implements the pairing and verification protocol. 2 | package pair 3 | -------------------------------------------------------------------------------- /hap/pair/errors.go: -------------------------------------------------------------------------------- 1 | package pair 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | ) 7 | 8 | var errInvalidClientKeyLength = errors.New("Invalid client public key size") 9 | 10 | var errInvalidPairMethod = func(m PairMethodType) error { 11 | return fmt.Errorf("Invalid pairing method %v\n", m) 12 | } 13 | 14 | var errInvalidPairStep = func(t PairStepType) error { 15 | return fmt.Errorf("Invalid pairing step %v\n", t) 16 | } 17 | 18 | var errInvalidInternalPairStep = func(t PairStepType) error { 19 | return fmt.Errorf("Invalid internal pairing step %v\n", t) 20 | } 21 | 22 | var errInvalidVerifyStep = func(t VerifyStepType) error { 23 | return fmt.Errorf("Invalid pairing verify step %v\n", t) 24 | } 25 | 26 | var errInvalidInternalVerifyStep = func(t VerifyStepType) error { 27 | return fmt.Errorf("Invalid internal pairing verify step %v\n", t) 28 | } 29 | -------------------------------------------------------------------------------- /hap/pair/handler.go: -------------------------------------------------------------------------------- 1 | package pair 2 | 3 | import ( 4 | "github.com/brutella/hc/hap" 5 | "github.com/brutella/hc/log" 6 | "github.com/brutella/hc/util" 7 | 8 | "io" 9 | ) 10 | 11 | // HandleReaderForHandler wraps h.Handle() call and logs sequence numbers and errors to the console. 12 | func HandleReaderForHandler(r io.Reader, h hap.ContainerHandler) (rOut io.Reader, err error) { 13 | in, err := util.NewTLV8ContainerFromReader(r) 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | log.Debug.Println("-> Seq:", in.GetByte(TagSequence)) 19 | 20 | out, err := h.Handle(in) 21 | 22 | if err != nil { 23 | log.Info.Println(err) 24 | } else { 25 | if out != nil { 26 | log.Debug.Println("<- Seq:", out.GetByte(TagSequence)) 27 | rOut = out.BytesBuffer() 28 | } 29 | } 30 | log.Debug.Println("--------------------------") 31 | 32 | return rOut, err 33 | } 34 | -------------------------------------------------------------------------------- /hap/pair/method_types.go: -------------------------------------------------------------------------------- 1 | package pair 2 | 3 | import "fmt" 4 | 5 | type PairMethodType byte 6 | 7 | const ( 8 | // PairingMethodDefault is the default pairing method. 9 | PairingMethodDefault PairMethodType = 0x00 10 | 11 | // PairingMethodMFi is used to pair with an MFi compliant accessory (not used). 12 | PairingMethodMFi PairMethodType = 0x01 13 | 14 | // PairingMethodAdd is used to pair a client by exchanging keys on a secured 15 | // connection and without going through the pairing process. 16 | PairingMethodAdd PairMethodType = 0x03 17 | 18 | // PairingMethodDelete is used to delete a pairing with a client. 19 | PairingMethodDelete PairMethodType = 0x04 20 | ) 21 | 22 | func (m PairMethodType) String() string { 23 | switch m { 24 | case PairingMethodDefault: 25 | return "Default" 26 | case PairingMethodMFi: 27 | return "MFi" 28 | case PairingMethodAdd: 29 | return "Add" 30 | case PairingMethodDelete: 31 | return "Delete" 32 | } 33 | return fmt.Sprintf("%v Unknown", byte(m)) 34 | } 35 | 36 | func (m PairMethodType) Byte() byte { 37 | return byte(m) 38 | } 39 | -------------------------------------------------------------------------------- /hap/pair/srp.go: -------------------------------------------------------------------------------- 1 | package pair 2 | 3 | import ( 4 | "github.com/tadglines/go-pkgs/crypto/srp" 5 | ) 6 | 7 | // Main SRP algorithm is described in http://srp.stanford.edu/design.html 8 | // The HAP uses the SRP-6a Stanford implementation with the following characteristics 9 | // x = H(s | H(I | ":" | P)) -> called the key derivative function 10 | // M1 = H(H(N) xor H(g), H(I), s, A, B, K) 11 | const ( 12 | SRPGroup = "rfc5054.3072" // N (modulo) => 384 byte 13 | ) 14 | 15 | // KeyDerivativeFuncRFC2945 returns the SRP-6a key derivative function which does 16 | // x = H(s | H(I | ":" | P)) 17 | func KeyDerivativeFuncRFC2945(h srp.HashFunc, username []byte) srp.KeyDerivationFunc { 18 | return func(salt, pin []byte) []byte { 19 | h := h() 20 | h.Write(username) 21 | h.Write([]byte(":")) 22 | h.Write(pin) 23 | t2 := h.Sum(nil) 24 | h.Reset() 25 | h.Write(salt) 26 | h.Write(t2) 27 | return h.Sum(nil) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /hap/secured_device.go: -------------------------------------------------------------------------------- 1 | package hap 2 | 3 | import ( 4 | "github.com/brutella/hc/db" 5 | ) 6 | 7 | // SecuredDevice is a HomeKit device with a pin. 8 | type SecuredDevice interface { 9 | Device 10 | Pin() string 11 | } 12 | 13 | type securedDevice struct { 14 | Device 15 | pin string 16 | } 17 | 18 | // NewSecuredDevice returns a device for a specific name either loaded from the database or newly created. 19 | // Additionally other device can only pair with by providing the correct pin. 20 | func NewSecuredDevice(name string, pin string, database db.Database) (SecuredDevice, error) { 21 | d, err := NewDevice(name, database) 22 | return &securedDevice{d, pin}, err 23 | } 24 | 25 | // Pin returns the device pin. 26 | func (d *securedDevice) Pin() string { 27 | return d.pin 28 | } 29 | -------------------------------------------------------------------------------- /log/log.go: -------------------------------------------------------------------------------- 1 | package log 2 | 3 | import ( 4 | "io/ioutil" 5 | "log" 6 | "os" 7 | ) 8 | 9 | var ( 10 | // Debug generates debug lines of output with a "DEBUG" prefix. 11 | // By default the lines are written to /dev/null. 12 | Debug = &Logger{log.New(ioutil.Discard, "DEBUG ", log.LstdFlags|log.Lshortfile)} 13 | 14 | // Info generates debug lines of output with a "INFO" prefix. 15 | // By default the lines are written to stdout. 16 | Info = &Logger{log.New(os.Stdout, "INFO ", log.LstdFlags|log.Lshortfile)} 17 | ) 18 | 19 | // Logger is a wrapper for log.Logger and provides 20 | // methods to enable and disable logging. 21 | type Logger struct { 22 | *log.Logger 23 | } 24 | 25 | // Disable sets the logging output to /dev/null. 26 | func (l *Logger) Disable() { 27 | l.SetOutput(ioutil.Discard) 28 | } 29 | 30 | // Enable sets the logging output to stdout. 31 | func (l *Logger) Enable() { 32 | l.SetOutput(os.Stdout) 33 | } 34 | -------------------------------------------------------------------------------- /password.go: -------------------------------------------------------------------------------- 1 | package hc 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "fmt" 7 | ) 8 | 9 | var invalidPins = []string{"12345678", "87654321", "00000000", "11111111", "22222222", "33333333", "44444444", "55555555", "66666666", "77777777", "88888888", "99999999"} 10 | 11 | // ValidatePin validates a HomeKit pin. 12 | func ValidatePin(pin string) (string, error) { 13 | var fmtPin string 14 | for _, invalidPin := range invalidPins { 15 | if pin == invalidPin { 16 | return fmtPin, fmt.Errorf("Pin must not be %s", pin) 17 | } 18 | } 19 | 20 | if len(pin) != 8 { 21 | return fmtPin, errors.New("Pin must be 8 characters long") 22 | } 23 | bs := []byte(pin) 24 | for _, b := range bs { 25 | if b < byte('0') || b > byte('9') { 26 | return fmtPin, errors.New("Pin must only contain numbers") 27 | } 28 | } 29 | runes := bytes.Runes(bs) 30 | first := string(runes[:3]) 31 | second := string(runes[3:5]) 32 | third := string(runes[5:]) 33 | fmtPin = first + "-" + second + "-" + third 34 | 35 | return fmtPin, nil 36 | } 37 | -------------------------------------------------------------------------------- /password_test.go: -------------------------------------------------------------------------------- 1 | package hc 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestPin(t *testing.T) { 8 | pwd, err := ValidatePin("00011222") 9 | if err != nil { 10 | t.Fatal(err) 11 | } 12 | if pwd != "000-11-222" { 13 | t.Fatal(pwd) 14 | } 15 | } 16 | 17 | func TestShortPin(t *testing.T) { 18 | if _, err := ValidatePin("0001122"); err == nil { 19 | t.Fatal("expected error") 20 | } 21 | } 22 | 23 | func TestLongPin(t *testing.T) { 24 | if _, err := ValidatePin("000112221"); err == nil { 25 | t.Fatal("expected error") 26 | } 27 | } 28 | 29 | func TestNonNumberPin(t *testing.T) { 30 | if _, err := ValidatePin("0001122a"); err == nil { 31 | t.Fatal("expected error") 32 | } 33 | } 34 | 35 | func TestInvalidPins(t *testing.T) { 36 | if _, err := ValidatePin("12345678"); err == nil { 37 | t.Fatal("expected error") 38 | } 39 | 40 | if _, err := ValidatePin("87654321"); err == nil { 41 | t.Fatal("expected error") 42 | } 43 | 44 | if _, err := ValidatePin("11111111"); err == nil { 45 | t.Fatal("expected error") 46 | } 47 | 48 | if _, err := ValidatePin("99999999"); err == nil { 49 | t.Fatal("expected error") 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /rtp/configuration.go: -------------------------------------------------------------------------------- 1 | package rtp 2 | 3 | type Configuration struct { 4 | Suites []SupportedCryptoSuite `tlv8:"-"` 5 | } 6 | 7 | func NewConfiguration(suite byte) Configuration { 8 | return Configuration{[]SupportedCryptoSuite{ 9 | SupportedCryptoSuite{suite}, 10 | }} 11 | } 12 | 13 | type SupportedCryptoSuite struct { 14 | Type byte `tlv8:"2"` 15 | } 16 | 17 | const ( 18 | CryptoSuite_AES_CM_128_HMAC_SHA1_80 byte = 0 19 | CryptoSuite_AES_256_CM_HMAC_SHA1_80 = 1 20 | CryptoSuiteNone = 2 21 | ) 22 | -------------------------------------------------------------------------------- /rtp/setup_endpoints_test.go: -------------------------------------------------------------------------------- 1 | package rtp 2 | 3 | import ( 4 | "github.com/brutella/hc/characteristic" 5 | "github.com/brutella/hc/tlv8" 6 | "testing" 7 | ) 8 | 9 | func TestSetupEndpoints(t *testing.T) { 10 | c := characteristic.NewSetupEndpoints() 11 | c.Value = "ARBz21VuCupGZre3A62biD8XAxkBAQACDDE5Mi4xNjguMC4xMwMC+OUEAurRBCUCEPpLBUWQEzkfFiGd1qkieqoDDi8cIMO0Vl1+kegzGgnpAQEABSUCEJQ27Ze9EEmuxcIVPhDEs68DDlaHwww6f6d5+NSClT7TAQEA" 12 | 13 | b := c.GetValue() 14 | 15 | var setup SetupEndpoints 16 | err := tlv8.Unmarshal(b, &setup) 17 | if err != nil { 18 | t.Fatal(err) 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /rtp/stream_configuration_test.go: -------------------------------------------------------------------------------- 1 | package rtp 2 | 3 | import ( 4 | "fmt" 5 | "github.com/brutella/hc/characteristic" 6 | "github.com/brutella/hc/tlv8" 7 | "testing" 8 | ) 9 | 10 | func TestSelectedStreamConfiguration(t *testing.T) { 11 | c := characteristic.NewSelectedStreamConfiguration() 12 | c.Value = "ARUCAQABEHW8tiJ9E0F4tLlvOURdFCc=" 13 | 14 | b := c.GetValue() 15 | 16 | var cfg StreamConfiguration 17 | err := tlv8.Unmarshal(b, &cfg) 18 | if err != nil { 19 | t.Fatal(err) 20 | } 21 | 22 | fmt.Printf("%+v", cfg) 23 | } 24 | -------------------------------------------------------------------------------- /rtp/stream_status.go: -------------------------------------------------------------------------------- 1 | package rtp 2 | 3 | type StreamingStatus struct { 4 | Status byte `tlv8:"1"` 5 | } 6 | 7 | const ( 8 | StreamingStatusAvailable byte = 0 9 | StreamingStatusBusy byte = 1 10 | StreamingStatusUnavailable byte = 2 11 | ) 12 | -------------------------------------------------------------------------------- /service/air_purifier.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeAirPurifier = "BB" 9 | 10 | type AirPurifier struct { 11 | *Service 12 | 13 | Active *characteristic.Active 14 | CurrentAirPurifierState *characteristic.CurrentAirPurifierState 15 | TargetAirPurifierState *characteristic.TargetAirPurifierState 16 | } 17 | 18 | func NewAirPurifier() *AirPurifier { 19 | svc := AirPurifier{} 20 | svc.Service = New(TypeAirPurifier) 21 | 22 | svc.Active = characteristic.NewActive() 23 | svc.AddCharacteristic(svc.Active.Characteristic) 24 | 25 | svc.CurrentAirPurifierState = characteristic.NewCurrentAirPurifierState() 26 | svc.AddCharacteristic(svc.CurrentAirPurifierState.Characteristic) 27 | 28 | svc.TargetAirPurifierState = characteristic.NewTargetAirPurifierState() 29 | svc.AddCharacteristic(svc.TargetAirPurifierState.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/air_quality_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeAirQualitySensor = "8D" 9 | 10 | type AirQualitySensor struct { 11 | *Service 12 | 13 | AirQuality *characteristic.AirQuality 14 | } 15 | 16 | func NewAirQualitySensor() *AirQualitySensor { 17 | svc := AirQualitySensor{} 18 | svc.Service = New(TypeAirQualitySensor) 19 | 20 | svc.AirQuality = characteristic.NewAirQuality() 21 | svc.AddCharacteristic(svc.AirQuality.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/battery_service.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeBatteryService = "96" 9 | 10 | type BatteryService struct { 11 | *Service 12 | 13 | BatteryLevel *characteristic.BatteryLevel 14 | ChargingState *characteristic.ChargingState 15 | StatusLowBattery *characteristic.StatusLowBattery 16 | } 17 | 18 | func NewBatteryService() *BatteryService { 19 | svc := BatteryService{} 20 | svc.Service = New(TypeBatteryService) 21 | 22 | svc.BatteryLevel = characteristic.NewBatteryLevel() 23 | svc.AddCharacteristic(svc.BatteryLevel.Characteristic) 24 | 25 | svc.ChargingState = characteristic.NewChargingState() 26 | svc.AddCharacteristic(svc.ChargingState.Characteristic) 27 | 28 | svc.StatusLowBattery = characteristic.NewStatusLowBattery() 29 | svc.AddCharacteristic(svc.StatusLowBattery.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/bridging_state.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeBridgingState = "62" 9 | 10 | type BridgingState struct { 11 | *Service 12 | 13 | Reachable *characteristic.Reachable 14 | LinkQuality *characteristic.LinkQuality 15 | AccessoryIdentifier *characteristic.AccessoryIdentifier 16 | Category *characteristic.Category 17 | } 18 | 19 | func NewBridgingState() *BridgingState { 20 | svc := BridgingState{} 21 | svc.Service = New(TypeBridgingState) 22 | 23 | svc.Reachable = characteristic.NewReachable() 24 | svc.AddCharacteristic(svc.Reachable.Characteristic) 25 | 26 | svc.LinkQuality = characteristic.NewLinkQuality() 27 | svc.AddCharacteristic(svc.LinkQuality.Characteristic) 28 | 29 | svc.AccessoryIdentifier = characteristic.NewAccessoryIdentifier() 30 | svc.AddCharacteristic(svc.AccessoryIdentifier.Characteristic) 31 | 32 | svc.Category = characteristic.NewCategory() 33 | svc.AddCharacteristic(svc.Category.Characteristic) 34 | 35 | return &svc 36 | } 37 | -------------------------------------------------------------------------------- /service/camera_control.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeCameraControl = "111" 9 | 10 | type CameraControl struct { 11 | *Service 12 | 13 | On *characteristic.On 14 | } 15 | 16 | func NewCameraControl() *CameraControl { 17 | svc := CameraControl{} 18 | svc.Service = New(TypeCameraControl) 19 | 20 | svc.On = characteristic.NewOn() 21 | svc.AddCharacteristic(svc.On.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/carbon_dioxide_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeCarbonDioxideSensor = "97" 9 | 10 | type CarbonDioxideSensor struct { 11 | *Service 12 | 13 | CarbonDioxideDetected *characteristic.CarbonDioxideDetected 14 | } 15 | 16 | func NewCarbonDioxideSensor() *CarbonDioxideSensor { 17 | svc := CarbonDioxideSensor{} 18 | svc.Service = New(TypeCarbonDioxideSensor) 19 | 20 | svc.CarbonDioxideDetected = characteristic.NewCarbonDioxideDetected() 21 | svc.AddCharacteristic(svc.CarbonDioxideDetected.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/carbon_monoxide_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeCarbonMonoxideSensor = "7F" 9 | 10 | type CarbonMonoxideSensor struct { 11 | *Service 12 | 13 | CarbonMonoxideDetected *characteristic.CarbonMonoxideDetected 14 | } 15 | 16 | func NewCarbonMonoxideSensor() *CarbonMonoxideSensor { 17 | svc := CarbonMonoxideSensor{} 18 | svc.Service = New(TypeCarbonMonoxideSensor) 19 | 20 | svc.CarbonMonoxideDetected = characteristic.NewCarbonMonoxideDetected() 21 | svc.AddCharacteristic(svc.CarbonMonoxideDetected.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/colored_lightbulb.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/brutella/hc/characteristic" 5 | ) 6 | 7 | type ColoredLightbulb struct { 8 | *Service 9 | 10 | On *characteristic.On 11 | Brightness *characteristic.Brightness 12 | Saturation *characteristic.Saturation 13 | Hue *characteristic.Hue 14 | } 15 | 16 | func NewColoredLightbulb() *ColoredLightbulb { 17 | svc := ColoredLightbulb{} 18 | svc.Service = New(TypeLightbulb) 19 | 20 | svc.On = characteristic.NewOn() 21 | svc.AddCharacteristic(svc.On.Characteristic) 22 | 23 | svc.Brightness = characteristic.NewBrightness() 24 | svc.AddCharacteristic(svc.Brightness.Characteristic) 25 | 26 | svc.Saturation = characteristic.NewSaturation() 27 | svc.AddCharacteristic(svc.Saturation.Characteristic) 28 | 29 | svc.Hue = characteristic.NewHue() 30 | svc.AddCharacteristic(svc.Hue.Characteristic) 31 | 32 | return &svc 33 | } 34 | -------------------------------------------------------------------------------- /service/contact_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeContactSensor = "80" 9 | 10 | type ContactSensor struct { 11 | *Service 12 | 13 | ContactSensorState *characteristic.ContactSensorState 14 | } 15 | 16 | func NewContactSensor() *ContactSensor { 17 | svc := ContactSensor{} 18 | svc.Service = New(TypeContactSensor) 19 | 20 | svc.ContactSensorState = characteristic.NewContactSensorState() 21 | svc.AddCharacteristic(svc.ContactSensorState.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/cooler.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/brutella/hc/characteristic" 5 | ) 6 | 7 | type Cooler struct { 8 | *HeaterCooler 9 | 10 | CoolingThresholdTemperature *characteristic.CoolingThresholdTemperature 11 | } 12 | 13 | func NewCooler() *Cooler { 14 | svc := Cooler{} 15 | 16 | svc.CoolingThresholdTemperature = characteristic.NewCoolingThresholdTemperature() 17 | svc.AddCharacteristic(svc.CoolingThresholdTemperature.Characteristic) 18 | 19 | return &svc 20 | } 21 | -------------------------------------------------------------------------------- /service/doc.go: -------------------------------------------------------------------------------- 1 | // Package service implements the HomeKit services. 2 | package service 3 | -------------------------------------------------------------------------------- /service/door.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeDoor = "81" 9 | 10 | type Door struct { 11 | *Service 12 | 13 | CurrentPosition *characteristic.CurrentPosition 14 | PositionState *characteristic.PositionState 15 | TargetPosition *characteristic.TargetPosition 16 | } 17 | 18 | func NewDoor() *Door { 19 | svc := Door{} 20 | svc.Service = New(TypeDoor) 21 | 22 | svc.CurrentPosition = characteristic.NewCurrentPosition() 23 | svc.AddCharacteristic(svc.CurrentPosition.Characteristic) 24 | 25 | svc.PositionState = characteristic.NewPositionState() 26 | svc.AddCharacteristic(svc.PositionState.Characteristic) 27 | 28 | svc.TargetPosition = characteristic.NewTargetPosition() 29 | svc.AddCharacteristic(svc.TargetPosition.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/doorbell.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeDoorbell = "121" 9 | 10 | type Doorbell struct { 11 | *Service 12 | 13 | ProgrammableSwitchEvent *characteristic.ProgrammableSwitchEvent 14 | } 15 | 16 | func NewDoorbell() *Doorbell { 17 | svc := Doorbell{} 18 | svc.Service = New(TypeDoorbell) 19 | 20 | svc.ProgrammableSwitchEvent = characteristic.NewProgrammableSwitchEvent() 21 | svc.AddCharacteristic(svc.ProgrammableSwitchEvent.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/fan.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeFan = "40" 9 | 10 | type Fan struct { 11 | *Service 12 | 13 | On *characteristic.On 14 | } 15 | 16 | func NewFan() *Fan { 17 | svc := Fan{} 18 | svc.Service = New(TypeFan) 19 | 20 | svc.On = characteristic.NewOn() 21 | svc.AddCharacteristic(svc.On.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/fan_v2.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeFanV2 = "B7" 9 | 10 | type FanV2 struct { 11 | *Service 12 | 13 | Active *characteristic.Active 14 | } 15 | 16 | func NewFanV2() *FanV2 { 17 | svc := FanV2{} 18 | svc.Service = New(TypeFanV2) 19 | 20 | svc.Active = characteristic.NewActive() 21 | svc.AddCharacteristic(svc.Active.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/faucet.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeFaucet = "D7" 9 | 10 | type Faucet struct { 11 | *Service 12 | 13 | Active *characteristic.Active 14 | } 15 | 16 | func NewFaucet() *Faucet { 17 | svc := Faucet{} 18 | svc.Service = New(TypeFaucet) 19 | 20 | svc.Active = characteristic.NewActive() 21 | svc.AddCharacteristic(svc.Active.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/filter_maintenance.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeFilterMaintenance = "BA" 9 | 10 | type FilterMaintenance struct { 11 | *Service 12 | 13 | FilterChangeIndication *characteristic.FilterChangeIndication 14 | } 15 | 16 | func NewFilterMaintenance() *FilterMaintenance { 17 | svc := FilterMaintenance{} 18 | svc.Service = New(TypeFilterMaintenance) 19 | 20 | svc.FilterChangeIndication = characteristic.NewFilterChangeIndication() 21 | svc.AddCharacteristic(svc.FilterChangeIndication.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/garage_door_opener.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeGarageDoorOpener = "41" 9 | 10 | type GarageDoorOpener struct { 11 | *Service 12 | 13 | CurrentDoorState *characteristic.CurrentDoorState 14 | TargetDoorState *characteristic.TargetDoorState 15 | ObstructionDetected *characteristic.ObstructionDetected 16 | } 17 | 18 | func NewGarageDoorOpener() *GarageDoorOpener { 19 | svc := GarageDoorOpener{} 20 | svc.Service = New(TypeGarageDoorOpener) 21 | 22 | svc.CurrentDoorState = characteristic.NewCurrentDoorState() 23 | svc.AddCharacteristic(svc.CurrentDoorState.Characteristic) 24 | 25 | svc.TargetDoorState = characteristic.NewTargetDoorState() 26 | svc.AddCharacteristic(svc.TargetDoorState.Characteristic) 27 | 28 | svc.ObstructionDetected = characteristic.NewObstructionDetected() 29 | svc.AddCharacteristic(svc.ObstructionDetected.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/heater.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/brutella/hc/characteristic" 5 | ) 6 | 7 | type Heater struct { 8 | *HeaterCooler 9 | 10 | HeatingThresholdTemperature *characteristic.HeatingThresholdTemperature 11 | } 12 | 13 | func NewHeater() *Heater { 14 | svc := Heater{} 15 | 16 | svc.HeatingThresholdTemperature = characteristic.NewHeatingThresholdTemperature() 17 | svc.AddCharacteristic(svc.HeatingThresholdTemperature.Characteristic) 18 | 19 | return &svc 20 | } 21 | -------------------------------------------------------------------------------- /service/heater_cooler.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeHeaterCooler = "BC" 9 | 10 | type HeaterCooler struct { 11 | *Service 12 | 13 | Active *characteristic.Active 14 | CurrentHeaterCoolerState *characteristic.CurrentHeaterCoolerState 15 | TargetHeaterCoolerState *characteristic.TargetHeaterCoolerState 16 | CurrentTemperature *characteristic.CurrentTemperature 17 | } 18 | 19 | func NewHeaterCooler() *HeaterCooler { 20 | svc := HeaterCooler{} 21 | svc.Service = New(TypeHeaterCooler) 22 | 23 | svc.Active = characteristic.NewActive() 24 | svc.AddCharacteristic(svc.Active.Characteristic) 25 | 26 | svc.CurrentHeaterCoolerState = characteristic.NewCurrentHeaterCoolerState() 27 | svc.AddCharacteristic(svc.CurrentHeaterCoolerState.Characteristic) 28 | 29 | svc.TargetHeaterCoolerState = characteristic.NewTargetHeaterCoolerState() 30 | svc.AddCharacteristic(svc.TargetHeaterCoolerState.Characteristic) 31 | 32 | svc.CurrentTemperature = characteristic.NewCurrentTemperature() 33 | svc.AddCharacteristic(svc.CurrentTemperature.Characteristic) 34 | 35 | return &svc 36 | } 37 | -------------------------------------------------------------------------------- /service/humidity_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeHumiditySensor = "82" 9 | 10 | type HumiditySensor struct { 11 | *Service 12 | 13 | CurrentRelativeHumidity *characteristic.CurrentRelativeHumidity 14 | } 15 | 16 | func NewHumiditySensor() *HumiditySensor { 17 | svc := HumiditySensor{} 18 | svc.Service = New(TypeHumiditySensor) 19 | 20 | svc.CurrentRelativeHumidity = characteristic.NewCurrentRelativeHumidity() 21 | svc.AddCharacteristic(svc.CurrentRelativeHumidity.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/irrigation_system.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeIrrigationSystem = "CF" 9 | 10 | type IrrigationSystem struct { 11 | *Service 12 | 13 | Active *characteristic.Active 14 | ProgramMode *characteristic.ProgramMode 15 | InUse *characteristic.InUse 16 | } 17 | 18 | func NewIrrigationSystem() *IrrigationSystem { 19 | svc := IrrigationSystem{} 20 | svc.Service = New(TypeIrrigationSystem) 21 | 22 | svc.Active = characteristic.NewActive() 23 | svc.AddCharacteristic(svc.Active.Characteristic) 24 | 25 | svc.ProgramMode = characteristic.NewProgramMode() 26 | svc.AddCharacteristic(svc.ProgramMode.Characteristic) 27 | 28 | svc.InUse = characteristic.NewInUse() 29 | svc.AddCharacteristic(svc.InUse.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/leak_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeLeakSensor = "83" 9 | 10 | type LeakSensor struct { 11 | *Service 12 | 13 | LeakDetected *characteristic.LeakDetected 14 | } 15 | 16 | func NewLeakSensor() *LeakSensor { 17 | svc := LeakSensor{} 18 | svc.Service = New(TypeLeakSensor) 19 | 20 | svc.LeakDetected = characteristic.NewLeakDetected() 21 | svc.AddCharacteristic(svc.LeakDetected.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/light_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeLightSensor = "84" 9 | 10 | type LightSensor struct { 11 | *Service 12 | 13 | CurrentAmbientLightLevel *characteristic.CurrentAmbientLightLevel 14 | } 15 | 16 | func NewLightSensor() *LightSensor { 17 | svc := LightSensor{} 18 | svc.Service = New(TypeLightSensor) 19 | 20 | svc.CurrentAmbientLightLevel = characteristic.NewCurrentAmbientLightLevel() 21 | svc.AddCharacteristic(svc.CurrentAmbientLightLevel.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/lightbulb.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeLightbulb = "43" 9 | 10 | type Lightbulb struct { 11 | *Service 12 | 13 | On *characteristic.On 14 | } 15 | 16 | func NewLightbulb() *Lightbulb { 17 | svc := Lightbulb{} 18 | svc.Service = New(TypeLightbulb) 19 | 20 | svc.On = characteristic.NewOn() 21 | svc.AddCharacteristic(svc.On.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/lock_management.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeLockManagement = "44" 9 | 10 | type LockManagement struct { 11 | *Service 12 | 13 | LockControlPoint *characteristic.LockControlPoint 14 | Version *characteristic.Version 15 | } 16 | 17 | func NewLockManagement() *LockManagement { 18 | svc := LockManagement{} 19 | svc.Service = New(TypeLockManagement) 20 | 21 | svc.LockControlPoint = characteristic.NewLockControlPoint() 22 | svc.AddCharacteristic(svc.LockControlPoint.Characteristic) 23 | 24 | svc.Version = characteristic.NewVersion() 25 | svc.AddCharacteristic(svc.Version.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/lock_mechanism.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeLockMechanism = "45" 9 | 10 | type LockMechanism struct { 11 | *Service 12 | 13 | LockCurrentState *characteristic.LockCurrentState 14 | LockTargetState *characteristic.LockTargetState 15 | } 16 | 17 | func NewLockMechanism() *LockMechanism { 18 | svc := LockMechanism{} 19 | svc.Service = New(TypeLockMechanism) 20 | 21 | svc.LockCurrentState = characteristic.NewLockCurrentState() 22 | svc.AddCharacteristic(svc.LockCurrentState.Characteristic) 23 | 24 | svc.LockTargetState = characteristic.NewLockTargetState() 25 | svc.AddCharacteristic(svc.LockTargetState.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/microphone.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeMicrophone = "112" 9 | 10 | type Microphone struct { 11 | *Service 12 | 13 | Volume *characteristic.Volume 14 | Mute *characteristic.Mute 15 | } 16 | 17 | func NewMicrophone() *Microphone { 18 | svc := Microphone{} 19 | svc.Service = New(TypeMicrophone) 20 | 21 | svc.Volume = characteristic.NewVolume() 22 | svc.AddCharacteristic(svc.Volume.Characteristic) 23 | 24 | svc.Mute = characteristic.NewMute() 25 | svc.AddCharacteristic(svc.Mute.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/motion_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeMotionSensor = "85" 9 | 10 | type MotionSensor struct { 11 | *Service 12 | 13 | MotionDetected *characteristic.MotionDetected 14 | } 15 | 16 | func NewMotionSensor() *MotionSensor { 17 | svc := MotionSensor{} 18 | svc.Service = New(TypeMotionSensor) 19 | 20 | svc.MotionDetected = characteristic.NewMotionDetected() 21 | svc.AddCharacteristic(svc.MotionDetected.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/occupancy_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeOccupancySensor = "86" 9 | 10 | type OccupancySensor struct { 11 | *Service 12 | 13 | OccupancyDetected *characteristic.OccupancyDetected 14 | } 15 | 16 | func NewOccupancySensor() *OccupancySensor { 17 | svc := OccupancySensor{} 18 | svc.Service = New(TypeOccupancySensor) 19 | 20 | svc.OccupancyDetected = characteristic.NewOccupancyDetected() 21 | svc.AddCharacteristic(svc.OccupancyDetected.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/outlet.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeOutlet = "47" 9 | 10 | type Outlet struct { 11 | *Service 12 | 13 | On *characteristic.On 14 | OutletInUse *characteristic.OutletInUse 15 | } 16 | 17 | func NewOutlet() *Outlet { 18 | svc := Outlet{} 19 | svc.Service = New(TypeOutlet) 20 | 21 | svc.On = characteristic.NewOn() 22 | svc.AddCharacteristic(svc.On.Characteristic) 23 | 24 | svc.OutletInUse = characteristic.NewOutletInUse() 25 | svc.AddCharacteristic(svc.OutletInUse.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/security_system.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeSecuritySystem = "7E" 9 | 10 | type SecuritySystem struct { 11 | *Service 12 | 13 | SecuritySystemCurrentState *characteristic.SecuritySystemCurrentState 14 | SecuritySystemTargetState *characteristic.SecuritySystemTargetState 15 | } 16 | 17 | func NewSecuritySystem() *SecuritySystem { 18 | svc := SecuritySystem{} 19 | svc.Service = New(TypeSecuritySystem) 20 | 21 | svc.SecuritySystemCurrentState = characteristic.NewSecuritySystemCurrentState() 22 | svc.AddCharacteristic(svc.SecuritySystemCurrentState.Characteristic) 23 | 24 | svc.SecuritySystemTargetState = characteristic.NewSecuritySystemTargetState() 25 | svc.AddCharacteristic(svc.SecuritySystemTargetState.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/service_label.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeServiceLabel = "CC" 9 | 10 | type ServiceLabel struct { 11 | *Service 12 | 13 | ServiceLabelNamespace *characteristic.ServiceLabelNamespace 14 | } 15 | 16 | func NewServiceLabel() *ServiceLabel { 17 | svc := ServiceLabel{} 18 | svc.Service = New(TypeServiceLabel) 19 | 20 | svc.ServiceLabelNamespace = characteristic.NewServiceLabelNamespace() 21 | svc.AddCharacteristic(svc.ServiceLabelNamespace.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/slat.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeSlat = "B9" 9 | 10 | type Slat struct { 11 | *Service 12 | 13 | SlatType *characteristic.SlatType 14 | CurrentSlatState *characteristic.CurrentSlatState 15 | } 16 | 17 | func NewSlat() *Slat { 18 | svc := Slat{} 19 | svc.Service = New(TypeSlat) 20 | 21 | svc.SlatType = characteristic.NewSlatType() 22 | svc.AddCharacteristic(svc.SlatType.Characteristic) 23 | 24 | svc.CurrentSlatState = characteristic.NewCurrentSlatState() 25 | svc.AddCharacteristic(svc.CurrentSlatState.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/smoke_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeSmokeSensor = "87" 9 | 10 | type SmokeSensor struct { 11 | *Service 12 | 13 | SmokeDetected *characteristic.SmokeDetected 14 | } 15 | 16 | func NewSmokeSensor() *SmokeSensor { 17 | svc := SmokeSensor{} 18 | svc.Service = New(TypeSmokeSensor) 19 | 20 | svc.SmokeDetected = characteristic.NewSmokeDetected() 21 | svc.AddCharacteristic(svc.SmokeDetected.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/speaker.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeSpeaker = "113" 9 | 10 | type Speaker struct { 11 | *Service 12 | 13 | Mute *characteristic.Mute 14 | } 15 | 16 | func NewSpeaker() *Speaker { 17 | svc := Speaker{} 18 | svc.Service = New(TypeSpeaker) 19 | 20 | svc.Mute = characteristic.NewMute() 21 | svc.AddCharacteristic(svc.Mute.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/stateful_programmable_switch.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeStatefulProgrammableSwitch = "88" 9 | 10 | type StatefulProgrammableSwitch struct { 11 | *Service 12 | 13 | ProgrammableSwitchEvent *characteristic.ProgrammableSwitchEvent 14 | ProgrammableSwitchOutputState *characteristic.ProgrammableSwitchOutputState 15 | } 16 | 17 | func NewStatefulProgrammableSwitch() *StatefulProgrammableSwitch { 18 | svc := StatefulProgrammableSwitch{} 19 | svc.Service = New(TypeStatefulProgrammableSwitch) 20 | 21 | svc.ProgrammableSwitchEvent = characteristic.NewProgrammableSwitchEvent() 22 | svc.AddCharacteristic(svc.ProgrammableSwitchEvent.Characteristic) 23 | 24 | svc.ProgrammableSwitchOutputState = characteristic.NewProgrammableSwitchOutputState() 25 | svc.AddCharacteristic(svc.ProgrammableSwitchOutputState.Characteristic) 26 | 27 | return &svc 28 | } 29 | -------------------------------------------------------------------------------- /service/stateless_programmable_switch.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeStatelessProgrammableSwitch = "89" 9 | 10 | type StatelessProgrammableSwitch struct { 11 | *Service 12 | 13 | ProgrammableSwitchEvent *characteristic.ProgrammableSwitchEvent 14 | } 15 | 16 | func NewStatelessProgrammableSwitch() *StatelessProgrammableSwitch { 17 | svc := StatelessProgrammableSwitch{} 18 | svc.Service = New(TypeStatelessProgrammableSwitch) 19 | 20 | svc.ProgrammableSwitchEvent = characteristic.NewProgrammableSwitchEvent() 21 | svc.AddCharacteristic(svc.ProgrammableSwitchEvent.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/switch.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeSwitch = "49" 9 | 10 | type Switch struct { 11 | *Service 12 | 13 | On *characteristic.On 14 | } 15 | 16 | func NewSwitch() *Switch { 17 | svc := Switch{} 18 | svc.Service = New(TypeSwitch) 19 | 20 | svc.On = characteristic.NewOn() 21 | svc.AddCharacteristic(svc.On.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/temperature_sensor.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeTemperatureSensor = "8A" 9 | 10 | type TemperatureSensor struct { 11 | *Service 12 | 13 | CurrentTemperature *characteristic.CurrentTemperature 14 | } 15 | 16 | func NewTemperatureSensor() *TemperatureSensor { 17 | svc := TemperatureSensor{} 18 | svc.Service = New(TypeTemperatureSensor) 19 | 20 | svc.CurrentTemperature = characteristic.NewCurrentTemperature() 21 | svc.AddCharacteristic(svc.CurrentTemperature.Characteristic) 22 | 23 | return &svc 24 | } 25 | -------------------------------------------------------------------------------- /service/time_information.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeTimeInformation = "99" 9 | 10 | type TimeInformation struct { 11 | *Service 12 | 13 | CurrentTime *characteristic.CurrentTime 14 | DayOfTheWeek *characteristic.DayOfTheWeek 15 | TimeUpdate *characteristic.TimeUpdate 16 | } 17 | 18 | func NewTimeInformation() *TimeInformation { 19 | svc := TimeInformation{} 20 | svc.Service = New(TypeTimeInformation) 21 | 22 | svc.CurrentTime = characteristic.NewCurrentTime() 23 | svc.AddCharacteristic(svc.CurrentTime.Characteristic) 24 | 25 | svc.DayOfTheWeek = characteristic.NewDayOfTheWeek() 26 | svc.AddCharacteristic(svc.DayOfTheWeek.Characteristic) 27 | 28 | svc.TimeUpdate = characteristic.NewTimeUpdate() 29 | svc.AddCharacteristic(svc.TimeUpdate.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/valve.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeValve = "D0" 9 | 10 | type Valve struct { 11 | *Service 12 | 13 | Active *characteristic.Active 14 | InUse *characteristic.InUse 15 | ValveType *characteristic.ValveType 16 | } 17 | 18 | func NewValve() *Valve { 19 | svc := Valve{} 20 | svc.Service = New(TypeValve) 21 | 22 | svc.Active = characteristic.NewActive() 23 | svc.AddCharacteristic(svc.Active.Characteristic) 24 | 25 | svc.InUse = characteristic.NewInUse() 26 | svc.AddCharacteristic(svc.InUse.Characteristic) 27 | 28 | svc.ValveType = characteristic.NewValveType() 29 | svc.AddCharacteristic(svc.ValveType.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/wifitransport.go: -------------------------------------------------------------------------------- 1 | package service 2 | 3 | import ( 4 | "github.com/brutella/hc/characteristic" 5 | ) 6 | 7 | const TypeWifiTransport = "22A" 8 | 9 | type WifiTransport struct { 10 | *Service 11 | 12 | CurrentTransport *characteristic.CurrentTransport 13 | WifiCapabilities *characteristic.WifiCapabilities 14 | WifiConfigurationControl *characteristic.WifiConfigurationControl 15 | } 16 | 17 | func NewWifiTransport() *WifiTransport { 18 | svc := WifiTransport{} 19 | svc.Service = New(TypeWifiTransport) 20 | 21 | svc.CurrentTransport = characteristic.NewCurrentTransport() 22 | svc.AddCharacteristic(svc.CurrentTransport.Characteristic) 23 | 24 | svc.WifiCapabilities = characteristic.NewWifiCapabilities() 25 | svc.AddCharacteristic(svc.WifiCapabilities.Characteristic) 26 | 27 | svc.WifiConfigurationControl = characteristic.NewWifiConfigurationControl() 28 | svc.AddCharacteristic(svc.WifiConfigurationControl.Characteristic) 29 | 30 | return &svc 31 | } 32 | -------------------------------------------------------------------------------- /service/window.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeWindow = "8B" 9 | 10 | type Window struct { 11 | *Service 12 | 13 | CurrentPosition *characteristic.CurrentPosition 14 | TargetPosition *characteristic.TargetPosition 15 | PositionState *characteristic.PositionState 16 | } 17 | 18 | func NewWindow() *Window { 19 | svc := Window{} 20 | svc.Service = New(TypeWindow) 21 | 22 | svc.CurrentPosition = characteristic.NewCurrentPosition() 23 | svc.AddCharacteristic(svc.CurrentPosition.Characteristic) 24 | 25 | svc.TargetPosition = characteristic.NewTargetPosition() 26 | svc.AddCharacteristic(svc.TargetPosition.Characteristic) 27 | 28 | svc.PositionState = characteristic.NewPositionState() 29 | svc.AddCharacteristic(svc.PositionState.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /service/window_covering.go: -------------------------------------------------------------------------------- 1 | // THIS FILE IS AUTO-GENERATED 2 | package service 3 | 4 | import ( 5 | "github.com/brutella/hc/characteristic" 6 | ) 7 | 8 | const TypeWindowCovering = "8C" 9 | 10 | type WindowCovering struct { 11 | *Service 12 | 13 | CurrentPosition *characteristic.CurrentPosition 14 | TargetPosition *characteristic.TargetPosition 15 | PositionState *characteristic.PositionState 16 | } 17 | 18 | func NewWindowCovering() *WindowCovering { 19 | svc := WindowCovering{} 20 | svc.Service = New(TypeWindowCovering) 21 | 22 | svc.CurrentPosition = characteristic.NewCurrentPosition() 23 | svc.AddCharacteristic(svc.CurrentPosition.Characteristic) 24 | 25 | svc.TargetPosition = characteristic.NewTargetPosition() 26 | svc.AddCharacteristic(svc.TargetPosition.Characteristic) 27 | 28 | svc.PositionState = characteristic.NewPositionState() 29 | svc.AddCharacteristic(svc.PositionState.Characteristic) 30 | 31 | return &svc 32 | } 33 | -------------------------------------------------------------------------------- /termination.go: -------------------------------------------------------------------------------- 1 | package hc 2 | 3 | import ( 4 | "os" 5 | "os/signal" 6 | "syscall" 7 | ) 8 | 9 | // TermFunc defines the function which is executed on termination. 10 | type TermFunc func() 11 | 12 | // OnTermination calls a function when the app receives an interrupt of kill signal. 13 | func OnTermination(fn TermFunc) { 14 | c := make(chan os.Signal) 15 | signal.Notify(c, os.Interrupt) 16 | signal.Notify(c, os.Kill) 17 | signal.Notify(c, syscall.SIGTERM) 18 | 19 | go func() { 20 | select { 21 | case <-c: 22 | if fn != nil { 23 | fn() 24 | } 25 | } 26 | }() 27 | } 28 | -------------------------------------------------------------------------------- /tlv8/marshal.go: -------------------------------------------------------------------------------- 1 | package tlv8 2 | 3 | func Marshal(v interface{}) ([]byte, error) { 4 | e := newEncoder() 5 | e.encode(v) 6 | return e.wr.bytes(), e.err 7 | } 8 | -------------------------------------------------------------------------------- /tlv8/unmarshal.go: -------------------------------------------------------------------------------- 1 | package tlv8 2 | 3 | import () 4 | 5 | func Unmarshal(data []byte, v interface{}) error { 6 | return unmarshal(data, v) 7 | } 8 | 9 | func unmarshal(data []byte, v interface{}) error { 10 | d, err := newDecoder(data) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | return d.decode(v) 16 | } 17 | -------------------------------------------------------------------------------- /tlv8/unmarshal_test.go: -------------------------------------------------------------------------------- 1 | package tlv8 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | type person struct { 8 | Name string `tlv8:"1"` 9 | Aliases []alias `tlv8:"-"` 10 | } 11 | 12 | type alias struct { 13 | Name string `tlv8:"3"` 14 | } 15 | 16 | var p = person{"Matthias", []alias{alias{"brutella"}, alias{"adsf"}}} 17 | 18 | func TestUnmarshalPerson(t *testing.T) { 19 | tlv8, err := Marshal(p) 20 | if err != nil { 21 | t.Fatal(err) 22 | } 23 | 24 | var pers person 25 | err = Unmarshal(tlv8, &pers) 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | if is, want := pers.Name, "Matthias"; is != want { 31 | t.Fatalf("is=%v want=%v", is, want) 32 | } 33 | 34 | if is, want := len(pers.Aliases), 2; is != want { 35 | t.Fatalf("is=%v want=%v", is, want) 36 | } 37 | 38 | if is, want := pers.Aliases[0].Name, "brutella"; is != want { 39 | t.Fatalf("is=%v want=%v", is, want) 40 | } 41 | 42 | if is, want := pers.Aliases[1].Name, "adsf"; is != want { 43 | t.Fatalf("is=%v want=%v", is, want) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /tlv8/writer_test.go: -------------------------------------------------------------------------------- 1 | package tlv8 2 | 3 | import ( 4 | "bytes" 5 | "reflect" 6 | "testing" 7 | ) 8 | 9 | func TestWriteBytes(t *testing.T) { 10 | wr := newWriter() 11 | 12 | buf := make([]byte, 256) 13 | wr.writeBytes(1, buf) 14 | 15 | expected := make([]byte, 260) 16 | expected[0] = 0x1 17 | expected[1] = 0xFF 18 | expected[257] = 0x1 19 | expected[258] = 0x1 20 | 21 | if is, want := wr.bytes(), expected; !reflect.DeepEqual(is, want) { 22 | t.Fatalf("%v != %v", is, want) 23 | } 24 | 25 | rd, err := newReader(bytes.NewBuffer(wr.bytes())) 26 | if err != nil { 27 | t.Fatal(err) 28 | } 29 | 30 | read, err := rd.readBytes(0x1) 31 | if err != nil { 32 | t.Fatal(err) 33 | } 34 | if is, want := read, buf; !reflect.DeepEqual(is, want) { 35 | t.Fatalf("%v len(%d) != %v len(%d)", is, len(is), want, len(want)) 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /transport.go: -------------------------------------------------------------------------------- 1 | package hc 2 | 3 | // Transport provides accessories over a network. 4 | type Transport interface { 5 | // Start starts the transport 6 | Start() 7 | 8 | // Stop stops the transport 9 | // Use the returned channel to wait until the transport is fully stopped. 10 | Stop() <-chan struct{} 11 | } 12 | -------------------------------------------------------------------------------- /util/container.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "bytes" 5 | ) 6 | 7 | // Container is a dictionary using byte keys and values. 8 | type Container interface { 9 | 10 | // SetByte sets one byte for a key 11 | SetByte(key, value byte) 12 | 13 | // SetBytes sets bytes for a key 14 | SetBytes(key byte, value []byte) 15 | 16 | // SetString sets a string for a key 17 | SetString(key byte, value string) 18 | 19 | // GetByte returns one byte for a key 20 | GetByte(key byte) byte 21 | 22 | // GetBytes returns bytes for a key 23 | GetBytes(key byte) []byte 24 | 25 | // GetString return a string for a key 26 | GetString(key byte) string 27 | 28 | // BytesBuffer returns the raw bytes 29 | BytesBuffer() *bytes.Buffer 30 | } 31 | -------------------------------------------------------------------------------- /util/doc.go: -------------------------------------------------------------------------------- 1 | // Package util provides utilities. 2 | package util 3 | -------------------------------------------------------------------------------- /util/mac.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/md5" 5 | "encoding/hex" 6 | "strings" 7 | ) 8 | 9 | // MAC48Address returns a MAC-48-like address from the argument string 10 | func MAC48Address(input string) string { 11 | h := md5.New() 12 | h.Write([]byte(input)) 13 | result := h.Sum(nil) 14 | 15 | var c []string 16 | c = append(c, toHex(result[0])) 17 | c = append(c, toHex(result[1])) 18 | c = append(c, toHex(result[2])) 19 | c = append(c, toHex(result[3])) 20 | c = append(c, toHex(result[4])) 21 | c = append(c, toHex(result[5])) 22 | 23 | // setup id needs the mac address in upper case 24 | return strings.ToUpper(strings.Join(c, ":")) 25 | } 26 | 27 | func toHex(b byte) string { 28 | return hex.EncodeToString([]byte{b}) 29 | } 30 | -------------------------------------------------------------------------------- /util/rand.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "crypto/rand" 5 | ) 6 | 7 | // RandomHexString returns a random hex string. 8 | func RandomHexString() string { 9 | var b [16]byte 10 | // Read might block 11 | // > crypto/rand: blocked for 60 seconds waiting to read random data from the kernel 12 | // > https://github.com/golang/go/commit/1961d8d72a53e780effa18bfa8dbe4e4282df0b2 13 | _, err := rand.Read(b[:]) 14 | if err != nil { 15 | panic(err) 16 | } 17 | var out [32]byte 18 | for i := 0; i < len(b); i++ { 19 | out[i*2] = btoh((b[i] >> 4) & 0xF) 20 | out[i*2+1] = btoh(b[i] & 0xF) 21 | } 22 | return string(out[:]) 23 | } 24 | 25 | func btoh(i byte) byte { 26 | if i > 9 { 27 | return 0x61 + (i - 10) 28 | } 29 | return 0x30 + i 30 | } 31 | -------------------------------------------------------------------------------- /util/rand_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "testing" 5 | ) 6 | 7 | func TestRandomHexString(t *testing.T) { 8 | s := RandomHexString() 9 | 10 | if x := len(s); x != 32 { 11 | t.Fatal(x) 12 | } 13 | 14 | for _, c := range s { 15 | if c >= 0x61 && c <= 0x66 { // a to f 16 | continue 17 | } 18 | if c >= 0x30 && c <= 0x39 { // 0 to 9 19 | continue 20 | } 21 | t.Fatalf("illegal hex character '%c'", c) 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /util/serial.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | // SerialFilenameForName returns the serial file name for a name 4 | func serialFilenameForName(name string) string { 5 | return name + ".serial" 6 | } 7 | 8 | // GetSerialNumberForAccessoryName returns the serial for a specific name stored in storage. 9 | // When no serial number is stored for this name yet, a new one is created 10 | // using RandomHexString() 11 | func GetSerialNumberForAccessoryName(name string, storage Storage) string { 12 | filename := serialFilenameForName(name) 13 | b, _ := storage.Get(filename) 14 | str := string(b) 15 | if len(str) == 0 { 16 | str = RandomHexString() 17 | storage.Set(filename, []byte(str)) 18 | } 19 | 20 | return str 21 | } 22 | -------------------------------------------------------------------------------- /util/serial_test.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestSerialForName(t *testing.T) { 9 | storage, err := NewTempFileStorage() 10 | if err != nil { 11 | t.Fatal(err) 12 | } 13 | 14 | name := "My Accessory" 15 | serial := GetSerialNumberForAccessoryName(name, storage) 16 | same := GetSerialNumberForAccessoryName(name, storage) 17 | 18 | if is, want := serial, same; reflect.DeepEqual(is, want) == false { 19 | t.Fatalf("is=%v want=%v", is, want) 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /util/storage.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | // Storage stores bytes for a key. 4 | type Storage interface { 5 | // Set sets bytes for a key 6 | Set(key string, value []byte) error 7 | 8 | // Delete removes bytes for a key 9 | Delete(key string) error 10 | 11 | // Get returns bytes for a key 12 | Get(key string) ([]byte, error) 13 | 14 | // KeysWithSuffix returns all keys with a specific suffix 15 | KeysWithSuffix(suffix string) ([]string, error) 16 | } 17 | -------------------------------------------------------------------------------- /util/string.go: -------------------------------------------------------------------------------- 1 | package util 2 | 3 | import ( 4 | "unicode" 5 | 6 | "golang.org/x/text/secure/precis" 7 | "golang.org/x/text/transform" 8 | "golang.org/x/text/unicode/norm" 9 | ) 10 | 11 | // RemoveAccentsFromString removes accent characters from string 12 | // From https://stackoverflow.com/a/40405242/424814 13 | func RemoveAccentsFromString(v string) string { 14 | var loosecompare = precis.NewIdentifier( 15 | precis.AdditionalMapping(func() transform.Transformer { 16 | return transform.Chain(norm.NFD, transform.RemoveFunc(func(r rune) bool { 17 | return unicode.Is(unicode.Mn, r) 18 | })) 19 | }), 20 | precis.Norm(norm.NFC), // This is the default; be explicit though. 21 | ) 22 | p, _ := loosecompare.String(v) 23 | return p 24 | } 25 | --------------------------------------------------------------------------------