go_fritzbox_api

package module
v0.0.0-...-2621133 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Dec 4, 2023 License: MIT Imports: 26 Imported by: 0

README

go fritzbox api

Quick & dirty API implementation for the AVM FRITZ!Box using Golang and REST.

Warning: There is no official API for some of these functions (except any smarthome-related stuff). This means, consistency across software-versions or different routers/repeaters is not guaranteed.

Attribution

This repository (structure, authentication) is based on Philipp Franke's implementation (go-fritzbox).

I added parsing for some endpoints and made some of his code worse in the process ;)

Contributing

Issues, Pull Requests and E-Mails are always welcome.

I accept suggestions for any new endpoints.

Compatiblity

This library works with FRITZ!OS 7.56 with the 6690 Cable. The smarthome-implementations (DECT) are stable and compatible with all versions and routers, except for any Pya endpoints and endpoints explicitely marked as unstable. These endpoints are neither consistent across versions nor backwards-compatible. They may also break unexpectedly.

Features

Smarthome: Using the official http-API, some types of smarthome-devices have been implemented. See the separate readme.

Clientlist:

  • GetCLientList Get all currently connected devices in a list.

  • Profile is empty by default (see Docs for more info)

Device: SetIP, SetName

Profiles: GetAvailableProfiles, GetProfileUIDFromDevice, SetProfileForDevice

Logs: GetEventLog, GetEventLogUntil

Statistics: GetTrafficStats

Custom Requests: (See examples)

Usage

I will eventually come around to writing a proper documentation. For now, you can look at the examples and check the godoc.

Setting Up the PyAdapter
pip install selenium-wire

Try running the script using commandline-args:

python pyAdapter/main.py OK;DEBUG;LOGIN http://192.168.178.1/ <current SID>

You can get an SID by logging into the Fritzbox in your brower and right-click + copying the link from (for example) one of the buttons in the top right (MyFritz, Fritz!Nas). The SID is contained in the link.

Remove the Debug if executing in headless (for example when connected via ssh):

python pyAdapter/main.py OK;LOGIN http://192.168.178.1/ <current SID>

Arguments can be given to the ChromeDriver like so:

python pyAdapter/main.py OK;DEBUG;ARGS --no-sandbox|--disable-gpu|disable-dev-shm-usage;LOGIN http://192.168.178.1/ <current SID>

If there are crashes, no-sandbox, disable-gpu and/or disable-dev-shm-usage are usually good arguments to try.

If that works and logs into the FritzBox, it should be okay to start the PyAdapter from the Go-Program.

Implementation

This Library is a Project I maintain and develop based on my personal needs. It's public because there aren't many maintained alternatives, not because I'm necessarily proud of its implementation. Code quality is not great, especially older code. There are no tests, because what I would really like to test (whether what I'm sending the FritzBox is still correct, for example after a FritzOS-Update) is very difficult to implement. For example, for Testing if changing the Name for a Device works, I would have to get some Device, change the Name, check if it worked, then change it back, without breaking anything in my internal Network. Doing this in a way that would also allow other people to execute these Tests is even more difficult.

Types of API-Endpoints

There are two (three) types of API-Endpoints used in this libary:

  • DECT: These are the endpoints used for smarthome-devices. They are documented in the official documentation and usually do not change. These Endpoints are implemented in the smarthome_-parts of this package and their respective Functions have the Prefix DECT.
  • Frontend Endpoints: POST-Request are sent to the FritzBox mimicking the Requests the Front-End would send during normal User Interaction. Because the required Parameters seem to change semi-regularly, all of these Endpoints are unstable and may break at any time. They are usually marked as Unstable in their GoDoc. In the beginning I was planning to use this type of Request for most of the Functionality I needed, but I quickly ran into a Roadblock with the Requests' Parameters. For Example when editing a Device, the Request sent by the Frontend always contains all the Devices' Parameters, even if they haven't changed. This means, no matter what Setting you want to change, you would have to get all the Parameters for a Device, change the one you want to change, then send all the Parameters back to the FritzBox. While sometimes, Parameters are optional in the Request, the FritzBox seems to reset these Params to their default if you don't send them. This proved basically impossible, because I would have to manually parse the Parameters for every Request from the respective Setting Pages HTML, then convert them to the Format the Request expects. Doing this for every Setting, and for every Value the given Setting can be set to, is unfeasible. Instead, this Type of Request is only used for Endpoints that fetch and parse Data, like the GetClientList-Endpoint (There are still older Endpoints that use this Type of Request, but I'm planning to change them at some point).
  • PYA Endpoints: What I came up with for the Problem described above are PYA Endpoints, where PYA stands for Python Adapter. When wanting to use PYA Endpoints, a PyAdapter-Struct has to be created and started. This will start the Python-Script which in turn starts a headless Chromedriver and listens to commands on stdin. The Chromedriver is used to send an "empty" Request to the FritzBox in order to retrieve the required Parameters, which are then returned to the Go-Program. After the Parameters have been retrieved, it is then simple to change the Parameter of the Setting we want to change and send the Post-Request to the FritBox. Retrieving the Parameters takes some Time (1-3 seconds), but generally, it's not much slower than some of the Endpoints of the official Smarthome-API. To improve the Time it takes to retrieve the Parameters, the PyAdapter is started concurrently to the Go-Program, meaning the Chromedriver is already started and logged in to the Fritzbox, which takes up to 7 seconds total. This means a "cold" start, where the PyAdapter first has to start and log in before sending the request can take up to 10 seconds. Further improvements to Speed can be made by caching the parameters, which I plan on doing at some point. However, caching will only work if no manual changes are made in the FritzBox-Interface to the given Device, because this would invalidate the cached Parameters and thus lead to the manual changes being overridden on the next change request. Currently the PYA expects the Webdriver in the PyAdapter directory or in the Path.

Roadmap

  • Better documentation
  • Pya Cache
  • Implementing more smarthome-capabilities/HanFun-interfaces
  • Implementing endpoints for smarthome-templates (gettemplatelistinfos, applytemplate)
Access remote fritzbox over ssl (untested)

See Philipp's example here

Documentation

Index

Constants

View Source
const (
	// DefaultSid is an invalid session in order to perform and
	// identify logouts.
	DefaultSid = "0000000000000000"
	// DefaultExpires is the amount of time of inactivity before
	// the FRITZ!Box automatically closes a session.
	DefaultExpires = 10 * time.Minute
)
View Source
const (
	RefreshSession      = true
	Timeout             = 10 * time.Second
	RefreshSessionDelay = 5 * time.Minute
)
View Source
const (
	CHanfun           = "HAN-FUN Gerät"
	CLicht            = "Licht/Lampe"
	CAlarm            = "Alarm-Sensor"
	CButton           = "AVM-Button"
	CHKR              = "Heizkörperregler"
	CEnergieMesser    = "Energie Messgerät"
	CTempSensor       = "Temperatursensor"
	CSteckdose        = "Schaltsteckdose"
	CRepeater         = "AVM DECT Repeater"
	CMikrofon         = "Mikrofon"
	CHanfunUnit       = "HAN-FUN-Units" // Sozusagen das "Kind" des Han-Fun-Geräts
	CSchaltbar        = "an-/ausschaltbares Gerät/Steckdose/Lampe/Aktor"
	CDimmbar          = "Gerät mit einstellbarem Dimm-, Höhen- bzw. Niveau-Level"
	CLampeMitFarbtemp = "Lampe mit einstellbarer Farbe/Farbtemperatur"
	CRollladen        = "Rollladen(Blind) - hoch, runter, stop und level 0% bis 100 %"

	EvTastendruckKurz = "lang"
	EvTastendruckLang = "kurz"
)

Beschreibung inkl. Fehler aus der Doku übernommen ;)

Variables

View Source
var (
	// ErrInvalidCred is the error returned by auth when
	// login attempt is not successful.
	ErrInvalidCred = errors.New("fritzbox: invalid credentials")

	// ErrExpiredSess means that Client was too long inactive.
	ErrExpiredSess = errors.New("fritzbox: session expired")
)

Functions

func GetCapability

func GetCapability[C Capability](d SmarthomeDevice) (r C)

Types

type Button

type Button struct {
	CapName    string
	Buttons    []ButtonPress
	Batterylow string
	Battery    string
	// contains filtered or unexported fields
}

func (*Button) Device

func (b *Button) Device() *SmarthomeDevice

func (*Button) Name

func (b *Button) Name() string

func (*Button) Reload

func (b *Button) Reload(c *Client) error

Reload reloads all client values

func (*Button) String

func (b *Button) String() string

type ButtonPress

type ButtonPress struct {
	ID                   string `json:"-id"`
	Type                 string
	Name                 string `json:"name"`
	Identifier           string `json:"-identifier"`
	LastPressedTimeStamp string `json:"lastpressedtimestamp"`
}

func (ButtonPress) GetLastPressTime

func (bp ButtonPress) GetLastPressTime() (t time.Time)

GetLastPressTime converts the last-press-time string to a time-struct

func (ButtonPress) String

func (bp ButtonPress) String() string

type Capabilities

type Capabilities map[string]Capability

Capabilities is a map of all available capabilities. They can be access using the Capability-Constants (starting with C, for example CHKR -> HeizungsKörperRegler, etc.) HasCapability can be used to check whether a device has a certain capability, without checking the map-keys.

func (Capabilities) String

func (c Capabilities) String() string

type Capability

type Capability interface {
	Name() string
	String() string
	Device() *SmarthomeDevice
	// contains filtered or unexported methods
}

type Client

type Client struct {
	BaseUrl  string
	Username string
	Password string
	// contains filtered or unexported fields
}

func (*Client) AddMACs

func (c *Client) AddMACs(cl *DeviceList) (err error)

func (*Client) AddProfiles

func (c *Client) AddProfiles(cl *DeviceList)

AddProfiles gets the profile for every device and adds it into an already existing Client-list. Warning: This will send one request per device, meaning it will take multiple seconds to complete. Alternatively, call GetProfileUIDFromDevice only for the devices you need

func (*Client) Close

func (c *Client) Close()

func (*Client) Copy

func (c *Client) Copy() *Client

func (*Client) CustomRequest

func (c *Client) CustomRequest(method string, urlPath string, data url.Values) (statusCode int, body string, err error)

CustomRequest allows one to send a custom request. The method can be http.MethodPost or http.MethodGet. The urlPath should always only be the path (for example "data.lua"), get-queries are set via the data-field. See examples.

func (*Client) GetAvailableProfiles

func (c *Client) GetAvailableProfiles() (profiles map[string]Profile, err error)

GetAvailableProfiles returns a map, where the Profile-Object is accessible via the profile-UID

func (*Client) GetCLientList

func (c *Client) GetCLientList() (clients DeviceList, err error)

func (*Client) GetDeviceInfos

func (c *Client) GetDeviceInfos(devIdentifier string, dest interface{}) (err error)

func (*Client) GetEventLog

func (c *Client) GetEventLog() (logEvents []LogMessage, err error)

func (*Client) GetEventLogUntil

func (c *Client) GetEventLogUntil(id int) (logEvents []LogMessage, err error)

GetEventLogUntil returns all log messages newer than the given id.

func (*Client) GetProfileUIDFromDevice

func (c *Client) GetProfileUIDFromDevice(deviceUID string) (profileUID string, err error)

GetProfileUIDFromDevice returns the UID of the profile that is assigned to the given device The return can be empty, for example for the fritzbox itself. This should be accounted for.

func (*Client) GetSmarthomeDevices

func (c *Client) GetSmarthomeDevices() (dl *SHDevicelist, err error)

func (*Client) GetSmarthomeDevicesFilter

func (c *Client) GetSmarthomeDevicesFilter(requiredCapabilities []string) (dl *SHDevicelist, err error)

func (*Client) GetTrafficStats

func (c *Client) GetTrafficStats() (ts TrafficStatistics, err error)

func (*Client) Initialize

func (c *Client) Initialize() error

func (*Client) IsInitialized

func (c *Client) IsInitialized() bool

func (*Client) SID

func (c *Client) SID() string

func (*Client) SetCustomHTTPClient

func (c *Client) SetCustomHTTPClient(client *http.Client)

func (*Client) SetIP

func (c *Client) SetIP(deviceUID string, ip string, static bool) (err error)

SetIP sets the IP address of a device like you would using the interface. Static indicated whether the given IP should be static and should always be true when changing the IP. Having it set to false is the same as un-ticking the checkbox in the edit dialog.

func (*Client) SetName

func (c *Client) SetName(deviceUID string, newName string) (err error)

SetName sets the name of a device. The name may only contain letters (a-z, A-Z), numerals (0-9), and hyphens (-).

func (*Client) SetProfileForDevice

func (c *Client) SetProfileForDevice(deviceUID string, profileUID string) (err error)

SetProfileForDevice (mainly untested) sets the profile from the profileUID to the device with the given deviceUID. Assigning the guest-Profile does not work when guest-wifi is off (makes sense), otherwise it might work

func (*Client) String

func (c *Client) String() string

type Device

type Device struct {
	UID             string `json:"UID"`
	Parent          string `json:"parent"`
	Category        string `json:"category"`
	Profile         Profile
	OwnClientDevice bool   `json:"own_client_device"`
	Dist            int    `json:"dist"`
	Switch          bool   `json:"switch"`
	Devtype         string `json:"devtype"`
	MAC             string `json:"mac"` // Note: AddMACs must be called for this field to not be empty
	Ownentry        bool   `json:"ownentry"`
	Stateinfo       struct {
		GuestOwe        bool `json:"guest_owe"`
		Active          bool `json:"active"`
		Meshable        bool `json:"meshable"`
		Guest           bool `json:"guest"`
		Online          bool `json:"online"`
		Blocked         bool `json:"blocked"`
		Realtime        bool `json:"realtime"`
		NotalloWed      bool `json:"notallowed"`
		InternetBlocked bool `json:"internetBlocked"`
	} `json:"stateinfo"`
	Conn       string `json:"conn"`
	Master     bool   `json:"master"`
	Detailinfo struct {
		Edit struct {
			Pid    string `json:"pid"`
			Params struct {
				Dev        string `json:"dev"`
				BackToPage string `json:"back_to_page"`
			} `json:"params"`
		} `json:"edit"`
		Portrelease bool `json:"portrelease"`
	} `json:"detailinfo"`
	Updateinfo struct {
		State string `json:"state"`
	} `json:"updateinfo"`
	Gateway  bool `json:"gateway"`
	Nameinfo struct {
		Name string `json:"name"`
	} `json:"nameinfo"`
	Children []interface{} `json:"children"`
	Conninfo struct {
		Kind     string `json:"kind"`
		Speed    string `json:"speed"`
		Bandinfo []struct {
			Band    int    `json:"band"`
			SpeedTx int    `json:"speed_tx"`
			SpeedRx int    `json:"speed_rx"`
			Speed   string `json:"speed"`
			Desc    string `json:"desc"`
		} `json:"bandinfo"`
		Usedbands int    `json:"usedbands"`
		Desc      string `json:"desc"`
	} `json:"conninfo"`
	Ipinfo string `json:"ipinfo"`
}

type DeviceList

type DeviceList struct {
	Rootuid string `json:"rootuid"`
	Devices []Device
}

type ETSIUnitInfo

type ETSIUnitInfo struct {
	ETSIDeviceID string `json:"etsideviceid"`
	Interface    string `json:"interfaces"`
	UnitType     string `json:"unittype"`
}

func (ETSIUnitInfo) GetInterfaceString

func (e ETSIUnitInfo) GetInterfaceString() string

GetInterfaceString returns the units interface-type as a string (values taken from documentation)

func (ETSIUnitInfo) GetUnitString

func (e ETSIUnitInfo) GetUnitString() string

GetUnitString returns the units type as a string (values taken from documentation)

func (ETSIUnitInfo) String

func (e ETSIUnitInfo) String() string

type HFAlert

type HFAlert struct {
	State          string `json:"state"`
	LastChangeTime string `json:"lastalertchgtimestamp"`
}

func (HFAlert) GetLastAlertTimestamp

func (hfa HFAlert) GetLastAlertTimestamp() time.Time

GetLastAlertTimestamp converts the last change timestamp into go time struct

func (HFAlert) IsAlertActive

func (hfa HFAlert) IsAlertActive() bool

IsAlertActive returns true is alert is active

func (HFAlert) String

func (hfa HFAlert) String() string

type HFColorControl

type HFColorControl struct {
}

func (HFColorControl) String

func (hfcc HFColorControl) String() string

type HFInterface

type HFInterface interface {
	String() string
	// contains filtered or unexported methods
}

type HFKeepAlive

type HFKeepAlive struct {
}

func (HFKeepAlive) String

func (hfka HFKeepAlive) String() string

type HFLevelControl

type HFLevelControl struct {
}

func (HFLevelControl) String

func (hflc HFLevelControl) String() string

type HFOnOff

type HFOnOff struct {
}

func (HFOnOff) String

func (hfoo HFOnOff) String() string

type HFOpenClose

type HFOpenClose struct {
}

func (HFOpenClose) String

func (hfoc HFOpenClose) String() string

type HFOpenCloseConfig

type HFOpenCloseConfig struct {
}

func (HFOpenCloseConfig) String

func (hfocc HFOpenCloseConfig) String() string

type HFSimpleButton

type HFSimpleButton struct {
}

func (HFSimpleButton) String

func (hfsb HFSimpleButton) String() string

type HFSuotaUpdate

type HFSuotaUpdate struct {
}

func (HFSuotaUpdate) String

func (hfsu HFSuotaUpdate) String() string

type HanFun

type HanFun struct {
	CapName string
	Units   HanFunUnits // A single HanFun-Device can potentially consist of multiple units
	// contains filtered or unexported fields
}

func (*HanFun) Device

func (hf *HanFun) Device() *SmarthomeDevice

func (*HanFun) GetInterface

func (hf *HanFun) GetInterface(i interface{}) interface{}

GetInterface returns a pointer to the requested interface if present, nil if not. For example: [...].GetInterface(HFAlert{}).(HFAlert)

func (*HanFun) HasInterface

func (hf *HanFun) HasInterface(i interface{}) bool

HasInterface returns true, if the given HanFun-Interface is present in the current devices' units For example: [...].HasInterface(HFAlert{})

func (*HanFun) Name

func (hf *HanFun) Name() string

func (*HanFun) Reload

func (hf *HanFun) Reload(c *Client) error

Reload reloads the device itself and all its units.

func (*HanFun) String

func (hf *HanFun) String() string

type HanFunUnit

type HanFunUnit struct {
	RawProperties map[string]json.RawMessage // Saves all properties of the unit in raw json-messages. Does not include values already represented (values present in the device-struct, as well as etsi-unit-info)
	ETSIUnitInfo  ETSIUnitInfo

	Interface HFInterface
	// contains filtered or unexported fields
}

func (*HanFunUnit) Device

func (h *HanFunUnit) Device() *SmarthomeDevice

func (*HanFunUnit) GetRawProperties

func (h *HanFunUnit) GetRawProperties() (s map[string]string, err error)

GetRawProperties returns the local interface-values as a string in json.

func (*HanFunUnit) IsUnitOfType

func (h *HanFunUnit) IsUnitOfType(t interface{}) bool

IsUnitOfType returns true if the units' interface is of the given type For example [...].IsUnitOfType(HFAlert{})

func (*HanFunUnit) Reload

func (h *HanFunUnit) Reload(c *Client) error

Reload fetches the device-information for this unit from the fritzbox and updates the structs' values

func (*HanFunUnit) String

func (h *HanFunUnit) String() string

func (*HanFunUnit) UnmarshalProperty

func (h *HanFunUnit) UnmarshalProperty(propertyKey string, dest interface{}) error

UnmarshalProperty unmarshals a property into the given interface

type HanFunUnits

type HanFunUnits []*HanFunUnit

func (HanFunUnits) String

func (hfus HanFunUnits) String() string

type Hkr

type Hkr struct {
	CapName                 string
	Tsoll                   string `json:"tsoll"`
	Absenk                  string `json:"absenk"`
	Komfort                 string `json:"komfort"`
	Lock                    string `json:"lock"`                    // Keylock (Tastensperre) configurated via Web-UI/API, activated automatically if summeractive or holdidayactive
	Devicelock              string `json:"devicelock"`              // Same as lock, configurated manually on the device itself
	Errorcode               string `json:"errorcode"`               // 0 = no error
	Windowopenactiv         string `json:"windowopenactiv"`         // 1 if window currently detected as open
	Windowopenactiveendtime string `json:"windowopenactiveendtime"` // time in seconds until radiator turns back on
	Boostactive             string `json:"boostactive"`             // same as window
	Boostactiveendtime      string `json:"boostactiveendtime"`      // same as window
	Batterylow              string `json:"batterylow"`              // 1 if battery low
	Battery                 string `json:"battery"`                 // battery %
	Nextchange              struct {
		Endperiod string `json:"endperiod"`
		Tchange   string `json:"tchange"`
	} `json:"nextchange"`
	Summeractive  string `json:"summeractive"`  // 1 if summer is currently active
	Holidayactive string `json:"holidayactive"` // same as summer

	// HkrUnstableInformation contains Information, that is not usually accessible via the API.
	// Empty by default. Call PyaFetchInformation on the Hkr to fill it using the PyAdapter.
	// SummerTime can be also fetched using FetchSummerTime (without PYA) or PyaFetchSummertime (with PYA)
	HkrUnstableInformation HkrPyaInformation `json:"-"`
	// contains filtered or unexported fields
}

Hkr is the struct for HeizungsKörperRegler. Note: current temperature can be accessed via the temperature-capability.

func (*Hkr) DECTDeactivateBoost

func (h *Hkr) DECTDeactivateBoost(c *Client) (err error)

DECTDeactivateBoost turns boost off if currently enabled

func (*Hkr) DECTDeactivateWindowOpen

func (h *Hkr) DECTDeactivateWindowOpen(c *Client) (err error)

func (*Hkr) DECTGetAbsenk

func (h *Hkr) DECTGetAbsenk(c *Client) (string, error)

DECTGetAbsenk is similar to DECTGetSoll

func (*Hkr) DECTGetAbsenkNumeric

func (h *Hkr) DECTGetAbsenkNumeric(c *Client) (float64, error)

DECTGetAbsenkNumeric is similar to DECTGetSollNumeric

func (*Hkr) DECTGetKomfort

func (h *Hkr) DECTGetKomfort(c *Client) (string, error)

DECTGetKomfort is similar to DECTGetSoll

func (*Hkr) DECTGetKomfortNumeric

func (h *Hkr) DECTGetKomfortNumeric(c *Client) (float64, error)

DECTGetKomfortNumeric is similar to DECTGetSollNumeric

func (*Hkr) DECTGetSoll

func (h *Hkr) DECTGetSoll(c *Client) (r string, err error)

DECTGetSoll sends an API-Request to get the current soll-temperature from the fritzbox/device itself. It will then update the current device locally and return the same output as GetSoll.

func (*Hkr) DECTGetSollNumeric

func (h *Hkr) DECTGetSollNumeric(c *Client) (float64, error)

DECTGetSollNumeric does the same as DECTGetSoll but returns the result like GetSollNumeric

func (*Hkr) DECTSetSoll

func (h *Hkr) DECTSetSoll(c *Client, sollTemp interface{}) error

DECTSetSoll sets the soll temperature to the given temperature (meaning 21.5 = 21.5 C). This method accepts float64/32, int and string (XX,X/ XX.X). Values with additional decimal places will be rounded to XX.0/XX.5 respectively. Only values from 8-28 are valid.

func (*Hkr) DECTSetSollMax

func (h *Hkr) DECTSetSollMax(c *Client) error

DECTSetSollMax turns the soll-temperature on. Allegedly, it should use the last known temperature. However, for me, it just sets the radiator to MAX.

func (*Hkr) DECTSetSollOff

func (h *Hkr) DECTSetSollOff(c *Client) error

DECTSetSollOff turns the soll-temperature off. The Hkr will show the snowflake in its display.

func (*Hkr) DECTSetWindowOpen

func (h *Hkr) DECTSetWindowOpen(c *Client, d time.Duration) (tm time.Time, err error)

func (*Hkr) Device

func (h *Hkr) Device() *SmarthomeDevice

func (*Hkr) FetchSummerTime

func (h *Hkr) FetchSummerTime(c *Client) (err error)

FetchSummerTime fetches the SummerTime-Frame for the HKR. It does not return anything, but instead fills the SummerTimeFrame-Field for the Hkr. If Pya is already initialized and logged in, using the Function PyaFetchSummertime is generally preferable.

func (*Hkr) GetAbsenk

func (h *Hkr) GetAbsenk() (r string)

GetAbsenk is similar to GetSoll

func (*Hkr) GetAbsenkNumeric

func (h *Hkr) GetAbsenkNumeric() float64

GetAbsenkNumeric is similar to GetSollNumeric

func (*Hkr) GetBoostEndtime

func (h *Hkr) GetBoostEndtime() (t time.Time)

GetBoostEndtime converts the endtime to a time-struct

func (*Hkr) GetErrorString

func (h *Hkr) GetErrorString() string

GetErrorString returns the error-message for the respective error-code. Errorcode 0 means no error. The error-messages originate from the official docs.

func (*Hkr) GetKomfort

func (h *Hkr) GetKomfort() (r string)

GetKomfort is similar to GetSoll

func (*Hkr) GetKomfortNumeric

func (h *Hkr) GetKomfortNumeric() float64

GetKomfortNumeric is similar to GetSollNumeric

func (*Hkr) GetNextChangeTemperature

func (h *Hkr) GetNextChangeTemperature() string

GetNextChangeTemperature returns the temperature, that the next change will set it to (as string)

func (*Hkr) GetNextChangeTemperatureNumeric

func (h *Hkr) GetNextChangeTemperatureNumeric() float64

GetNextChangeTemperatureNumeric returns the temperature, that the next change will set it to (numeric)

func (*Hkr) GetNextchangeEndtime

func (h *Hkr) GetNextchangeEndtime() (t time.Time)

GetNextchangeEndtime returns the time of the next temperature-change

func (*Hkr) GetSoll

func (h *Hkr) GetSoll() (r string)

GetSoll returns the same values as GetSollNumeric, but as a string. Instead of -1 and -2, it returns "OFF" or "MAX"

func (*Hkr) GetSollNumeric

func (h *Hkr) GetSollNumeric() float64

GetSollNumeric returns the current locally saved soll-temperature. It returns temperatures in Celsius from 8-28, as well as -1 (MAX) -2 (OFF).

func (*Hkr) GetWindowOpenEndtime

func (h *Hkr) GetWindowOpenEndtime() (t time.Time)

func (*Hkr) IsBatteryLow

func (h *Hkr) IsBatteryLow() bool

IsBatteryLow returns true if the device reports battery low

func (*Hkr) IsBoostActive

func (h *Hkr) IsBoostActive() bool

IsBoostActive returns true, if the boost is currently active No API-requests are made. Instead, all this does is convert the local value. Only functions with the DECT-Prefix communicate with the fritzbox.

func (*Hkr) IsHolidayActive

func (h *Hkr) IsHolidayActive() bool

IsHolidayActive returns true, if holiday-mode is currently active

func (*Hkr) IsSummerActive

func (h *Hkr) IsSummerActive() bool

IsSummerActive returns true, if summer-mode is currently active

func (*Hkr) IsWindowOpen

func (h *Hkr) IsWindowOpen() bool

func (*Hkr) Name

func (h *Hkr) Name() string

func (*Hkr) PyaDisableAllHolidays

func (h *Hkr) PyaDisableAllHolidays(pya *PyAdapter) (err error)

func (*Hkr) PyaDisableCurrentHoliday

func (h *Hkr) PyaDisableCurrentHoliday(pya *PyAdapter) (err error)

PyaDisableCurrentHoliday disables the currently active Holiday using the PYA. If no Holiday is currently active, an error is returned.

func (*Hkr) PyaDisableHoliday

func (h *Hkr) PyaDisableHoliday(pya *PyAdapter, hol Holiday) (err error)

PyaDisableHoliday disables the given Holiday using the PYA.

func (*Hkr) PyaDisableSummerTime

func (h *Hkr) PyaDisableSummerTime(pya *PyAdapter) (err error)

PyaDisableSummerTime disables the SummerTime for the HKR.

func (*Hkr) PyaFetchInformation

func (h *Hkr) PyaFetchInformation(pya *PyAdapter) (err error)

PyaFetchInformation fetches the SummerTimeFrame, the Zeitschaltung and the Holiday-Fields for HkrUnstableInformation. It does not return anything, but instead fills the HkrUnstableInformation-Field of the Hkr. There is only one Method to fill all three fields at once, as they are all fetched using the same initial request, thus making fetching all three of them separately much slower than just fetching them together. This Method is preferred over FetchSummerTime, as it does not require parsing the HTML-Response, thus (hopefully) making it more stable.

func (*Hkr) PyaSetHolidays

func (h *Hkr) PyaSetHolidays(pya *PyAdapter, holidays Holidays) (err error)

PyaSetHolidays sets the Holidays for the HKR. Please see the Documentation for Holidays.

func (*Hkr) PyaSetSummerTime

func (h *Hkr) PyaSetSummerTime(pya *PyAdapter, st SummerTime) (err error)

PyaSetSummerTime sets the SummerTime for the HKR. Only Day/Month of the Time-Values is required. The Helper-Method DateFromMD can be used to create the Time-Values.

func (*Hkr) PyaSetZeitschaltung

func (h *Hkr) PyaSetZeitschaltung(pya *PyAdapter, z Zeitschaltung) (err error)

PyaSetZeitschaltung sets the Zeitschaltung for the HKR. Please see the Documentation for Zeitschaltung.

func (*Hkr) Reload

func (h *Hkr) Reload(c *Client) error

Reload reloads all client values

func (*Hkr) SetBoost

func (h *Hkr) SetBoost(c *Client, d time.Duration) (tm time.Time, err error)

SetBoost activates the radiators boost-function for the specified duration (max. 24hrs). Returns the end-time of the boost.

func (*Hkr) String

func (h *Hkr) String() string

type HkrPyaInformation

type HkrPyaInformation struct {
	SummerTime    SummerTime
	Zeitschaltung Zeitschaltung
	Holidays      Holidays
}

HkrPyaInformation contains Information, that is not usually accessible via the API. Empty by default. Call PyaFetchInformation on the Hkr to fill it using the PyAdapter.

type Holiday

type Holiday struct {
	ID         int
	StartDay   int
	StartMonth int
	StartHour  int
	EndDay     int
	EndMonth   int
	EndHour    int
	Enabled    int
}

Holiday is a single Holiday. It consists of a Start and End time, as well as an ID. For creating Holidays, use Holidays.AddHoliday.

func (*Holiday) GetEndDate

func (h *Holiday) GetEndDate() time.Time

GetEndDate converts the End-Values to a time.Time-Struct

func (*Holiday) GetStartDate

func (h *Holiday) GetStartDate() time.Time

GetStartDate converts the Start-Values to a time.Time-Struct

func (*Holiday) IsEmpty

func (h *Holiday) IsEmpty() bool

IsEmpty returns true if the given Holiday is empty

func (*Holiday) IsEnabled

func (h *Holiday) IsEnabled() bool

IsEnabled returns true if the given Holiday is enabled

func (Holiday) String

func (h Holiday) String() string

type Holidays

type Holidays struct {
	Holidays    [4]Holiday
	HolidayTemp float64
}

Holidays is the Struct that is used to set Holidays for the HKR. The FritzBox allows a maximum of 4 Holidays.

func (*Holidays) AddHoliday

func (h *Holidays) AddHoliday(from time.Time, to time.Time) error

AddHoliday adds a Holiday to the Holidays-Struct. Helper Method. No Request is sent. It returns an error if the maximum amount of Holidays is reached. Holidays added via this Method are enabled by default. There can be 0-4 Holidays total.

func (Holidays) String

func (h Holidays) String() string

func (*Holidays) ToValues

func (h *Holidays) ToValues() map[string]string

ToValues converts the Holidays to a map[string]string, which is the Format the FritzBox expects.

func (*Holidays) Validate

func (h *Holidays) Validate(stf SummerTime) error

Validate checks if the Holidays are valid. It returns an error if the Holidays are invalid. Holidays are invalid, if any Holidays overlap, or if the Start is after the End-Date of the same Holiday.

type LogMessage

type LogMessage struct {
	DateTime time.Time
	Date     string `json:"date"`
	Group    string `json:"group"`
	ID       int    `json:"id"`
	Message  string `json:"msg"`
	Time     string `json:"time"`
}

type Profile

type Profile struct {
	Name   string
	UID    string
	Filter string
}

type PyAdapter

type PyAdapter struct {
	Client       *Client
	Debug        bool
	BrowserDebug bool
	// DriverArgs are the arguments that are passed to the chromedriver using options.add_argument()
	DriverArgs []string
	// contains filtered or unexported fields
}

PyAdapter is a struct that controls the Python Adapter to Selenium. The Python Implementation of Selenium Wire is used to fetch the Arguments that are required for specific Requests.

Starting a Python-Adapter will result in a Chromedriver being started in the Background and a Session for the Fritz!Box being created. This Session is automatically refreshed periodically, unless RefreshSession is set to false. For more Information, see the Readme (todo)

func (*PyAdapter) GetArgsHKR

func (pya *PyAdapter) GetArgsHKR(device Hkr) (params map[string]string, err error)

func (*PyAdapter) StartAdapter

func (pya *PyAdapter) StartAdapter() error

StartAdapter starts the Python Script, logs in and starts the sessionRefresher if RefreshSession is set to true.

func (*PyAdapter) StopPyAdapter

func (pya *PyAdapter) StopPyAdapter() error

type SHDevicelist

type SHDevicelist struct {
	Version   string
	Fwversion string
	Devices   []SmarthomeDevice
	// contains filtered or unexported fields
}

func (*SHDevicelist) Reload

func (dl *SHDevicelist) Reload(c *Client) error

func (*SHDevicelist) String

func (dl *SHDevicelist) String() string

type SlotTemplate

type SlotTemplate struct {
	Weekday time.Weekday
	Start   string
	End     string
}

SlotTemplate is a helper for creating Slots. It consists of a Weekday, a Start and an End time. To create a Slot for Monday, from 11 AM - 3 PM (11-15:00), use SlotTemplate{time.Monday, "11:00", "15:00"} The Slots created this Way can then be added to the Zeitschaltung using Zeitschaltung.SlotFromTemplate or Zeitschaltung.SlotsFromTemplates

type SmarthomeDevice

type SmarthomeDevice struct {
	Identifier   string
	ID           string
	Fwversion    string
	Manufacturer string
	Productname  string
	Txbusy       string
	Name         string
	Present      string
	Capabilities Capabilities
}

SmarthomeDevice is the main type for fritz-smarthome-devices. It only holds values all devices have, all other properties are handled in their respective capabilities.

func (*SmarthomeDevice) DECTGetName

func (d *SmarthomeDevice) DECTGetName(c *Client) (string, error)

DECTGetName fetches device-Name from the fritzbox and updates internally stored value.

func (*SmarthomeDevice) DECTIsSwitchPrsent

func (d *SmarthomeDevice) DECTIsSwitchPrsent(c *Client) (bool, error)

DECTIsSwitchPrsent fetches current status from the fritzbox and updates internally stored value. Note: According to the documentation, it may take multiple minutes for the status to update after a device disconnected.

func (*SmarthomeDevice) DECTSetName

func (d *SmarthomeDevice) DECTSetName(c *Client, name string) error

DECTSetName updates device Name based on identifier and updates internal values if successful

func (*SmarthomeDevice) HasCapability

func (d *SmarthomeDevice) HasCapability(cap string) bool

HasCapability returns true, if device has given capability. Use capability-constants.

func (*SmarthomeDevice) IsSwitchPrsent

func (d *SmarthomeDevice) IsSwitchPrsent() bool

IsSwitchPrsent returns true if device is present. Uses locally stored value.

func (*SmarthomeDevice) Reload

func (d *SmarthomeDevice) Reload(cl *Client) error

func (*SmarthomeDevice) String

func (d *SmarthomeDevice) String() string

type SummerTime

type SummerTime struct {
	IsEnabled  bool
	StartDay   string
	StartMonth string
	EndDay     string
	EndMonth   string
}

SummerTime is the field that holds Information about the Start- and End-Date of the SummerTime-Frame set for the HKR. The struct only holds the raw Information as Strings. To get the actual Dates, use GetStartDate and GetEndDate. To fetch the Data, use FetchSummerTime (without PYA) or PyaFetchSummertime (with PYA).

func (*SummerTime) FromDates

func (stf *SummerTime) FromDates(start time.Time, end time.Time)

FromDates allows the Creation of a SummerTime struct using two dates

func (*SummerTime) GetEndDate

func (stf *SummerTime) GetEndDate() time.Time

GetEndDate returns a formatted time.Time-Struct for the End of the SummerTime-Frame

func (*SummerTime) GetStartDate

func (stf *SummerTime) GetStartDate() time.Time

GetStartDate returns a formatted time.Time-Struct for the Start of the SummerTime-Frame

func (*SummerTime) IsEmpty

func (stf *SummerTime) IsEmpty() bool

IsEmpty returns true, if the SummerTime is empty or not enabled.

func (SummerTime) String

func (stf SummerTime) String() string

func (*SummerTime) Validate

func (stf *SummerTime) Validate(holidays Holidays) (err error)

Validate checks, if the SummerTime is valid. For this, it needs the Holidays, as SummerTime and Holidays cannot overlap. Validation happens automatically on the call of PyaSetSummerTime, with no additional time cost for fetching the holidays.

type Tag

type Tag struct {
	Tag   time.Weekday
	Slots []ZeitSlot
}

Tag is a Part of Zeitschaltung. Every Tag has a Weekday and a list of ZeitSlots.

type Temperature

type Temperature struct {
	CapName string
	Celsius string `json:"celsius"`
	Offset  string `json:"offset"`
	// contains filtered or unexported fields
}

func (*Temperature) DECTGetCelsiusNumeric

func (t *Temperature) DECTGetCelsiusNumeric(c *Client) (float64, error)

DECTGetCelsiusNumeric is the same as GetIstNumeric, but it will fetch the current value from the fritzbox and update the local state of the device before returning.

func (*Temperature) DECTGetDeviceStats

func (t *Temperature) DECTGetDeviceStats(c *Client) (ts TemperatureStats, err error)

DECTGetDeviceStats returns the temperatures measured from the device in the last 24 hours

func (*Temperature) Device

func (t *Temperature) Device() *SmarthomeDevice

func (*Temperature) GetCelsiusNumeric

func (t *Temperature) GetCelsiusNumeric() float64

GetCelsiusNumeric returns the temperature reading in float converted to the usual format (eg. 21.5)

func (*Temperature) GetOffsetNumeric

func (t *Temperature) GetOffsetNumeric() float64

GetOffsetNumeric returns the temperature offset set for the device in float converted to the usual format (eg. 21.5)

func (*Temperature) Name

func (t *Temperature) Name() string

func (*Temperature) PyaSetOffset

func (t *Temperature) PyaSetOffset(pya *PyAdapter, offset float64) (err error)

PyaSetOffset sets the temperature offset for the device using the PyAdapter

func (*Temperature) Reload

func (t *Temperature) Reload(c *Client) error

Reload fetches the current device and updates the current capability

func (*Temperature) String

func (t *Temperature) String() string

type TemperatureStats

type TemperatureStats struct {
	Values                     []float64
	AmountOfValues             int
	SecondsBetweenMeasurements int
}

func (TemperatureStats) String

func (ts TemperatureStats) String() string

type TrafficForDuration

type TrafficForDuration struct {
	BytesSentHigh     string `json:"BytesSentHigh"`
	BytesSentLow      string `json:"BytesSentLow"`
	BytesReceivedHigh string `json:"BytesReceivedHigh"`
	BytesReceivedLow  string `json:"BytesReceivedLow"`
	MBSent            int
	MBReceived        int
}

The TrafficForDuration struct contains network statistics. Only MBSent and MBReceived are real values. The rest are raw values returned by the backend.

func (*TrafficForDuration) String

func (tfd *TrafficForDuration) String() string

type TrafficStatistics

type TrafficStatistics struct {
	LastMonth TrafficForDuration `json:"LastMonth"`
	ThisWeek  TrafficForDuration `json:"ThisWeek"`
	Today     TrafficForDuration `json:"Today"`
	Yesterday TrafficForDuration `json:"Yesterday"`
	ThisMonth TrafficForDuration `json:"ThisMonth"`
}

func (*TrafficStatistics) String

func (ts *TrafficStatistics) String() string

type ZeitSlot

type ZeitSlot struct {
	Start time.Time
	End   time.Time
}

ZeitSlot is a Part of Tag. It consists of a Start and End time of the given Slot.

type Zeitschaltung

type Zeitschaltung struct {
	Tage []Tag
}

Zeitschaltung is a struct that holds the Values for the HKR-Timer in the Format that is expected by the Fritzbox. It consists of all days of the week, which in turn consist of ZeitSlots.

func (*Zeitschaltung) SlotFromStrings

func (z *Zeitschaltung) SlotFromStrings(weekday time.Weekday, start string, end string) (err error)

SlotFromStrings creates a Slot from a Weekday and two Strings (Start and End time) and adds it to the Zeitschaltung.

func (*Zeitschaltung) SlotFromTemplate

func (z *Zeitschaltung) SlotFromTemplate(data SlotTemplate) (err error)

SlotFromTemplate creates a Slot from a SlotTemplate and adds it to the Zeitschaltung.

func (*Zeitschaltung) SlotsFromTemplates

func (z *Zeitschaltung) SlotsFromTemplates(data []SlotTemplate) (err error)

SlotsFromTemplates creates Slots from multiple SlotTemplates and adds them to the Zeitschaltung.

func (Zeitschaltung) String

func (z Zeitschaltung) String() string

func (*Zeitschaltung) ToValues

func (z *Zeitschaltung) ToValues() map[string]string

ToValues converts the Zeitschaltung to a map[string]string, which is the Format the FritzBox expects.

func (*Zeitschaltung) Validate

func (z *Zeitschaltung) Validate() error

Validate checks if the Zeitschaltung is valid. It returns an error if the Zeitschaltung is invalid. This Method is automatically called when PyaSetZeitschaltung is called, but it may be called in addition manually to check User-Input.

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL