Bluelink: fix handling of stamps (#2936)
This commit is contained in:
parent
37f4a5679f
commit
6787bd464e
2 changed files with 55 additions and 64 deletions
|
|
@ -55,19 +55,15 @@ func NewIdentity(log *util.Logger, config Config) *Identity {
|
|||
config: config,
|
||||
}
|
||||
|
||||
// fetch updated stamps
|
||||
updateStamps(log, config.CCSPApplicationID)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
// Credits to https://openwb.de/forum/viewtopic.php?f=5&t=1215&start=10#p11877
|
||||
|
||||
func (v *Identity) stamp() string {
|
||||
return Stamps.New(v.config.CCSPApplicationID)
|
||||
}
|
||||
|
||||
func (v *Identity) getDeviceID() (string, error) {
|
||||
stamp, err := Stamps[v.config.CCSPApplicationID].Get()
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
uniID, _ := uuid.NewUUID()
|
||||
data := map[string]interface{}{
|
||||
"pushRegId": "1",
|
||||
|
|
@ -79,7 +75,7 @@ func (v *Identity) getDeviceID() (string, error) {
|
|||
"ccsp-service-id": v.config.CCSPServiceID,
|
||||
"Content-type": "application/json;charset=UTF-8",
|
||||
"User-Agent": "okhttp/3.10.0",
|
||||
"Stamp": v.stamp(),
|
||||
"Stamp": stamp,
|
||||
}
|
||||
|
||||
var resp struct {
|
||||
|
|
@ -362,6 +358,11 @@ func (v *Identity) Login(user, password, language string) (err error) {
|
|||
|
||||
// Request decorates requests with authorization headers
|
||||
func (v *Identity) Request(req *http.Request) error {
|
||||
stamp, err := Stamps[v.config.CCSPApplicationID].Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
token, err := v.Token()
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
@ -373,7 +374,7 @@ func (v *Identity) Request(req *http.Request) error {
|
|||
"ccsp-application-id": v.config.CCSPApplicationID,
|
||||
"offset": "1",
|
||||
"User-Agent": "okhttp/3.10.0",
|
||||
"Stamp": v.stamp(),
|
||||
"Stamp": stamp,
|
||||
} {
|
||||
req.Header.Set(k, v)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -15,72 +15,62 @@ const (
|
|||
HyundaiAppID = "014d2225-8495-4735-812d-2616334fd15d"
|
||||
)
|
||||
|
||||
// StampsRegistry collects stamps for a single brand
|
||||
type StampsRegistry map[string]*StampCollection
|
||||
|
||||
type StampCollection struct {
|
||||
Stamps []string
|
||||
Generated time.Time
|
||||
Frequency float64
|
||||
}
|
||||
|
||||
var Stamps = StampsRegistry{
|
||||
KiaAppID: nil,
|
||||
HyundaiAppID: nil,
|
||||
type stampCollection struct {
|
||||
mu sync.Mutex
|
||||
log *util.Logger
|
||||
AppID, Brand string
|
||||
Stamps []string
|
||||
Generated time.Time
|
||||
Frequency float64
|
||||
updated time.Time
|
||||
}
|
||||
|
||||
var (
|
||||
mu sync.Mutex
|
||||
updater map[string]struct{} = make(map[string]struct{})
|
||||
|
||||
client = request.NewHelper(util.NewLogger("http"))
|
||||
brands = map[string]string{
|
||||
KiaAppID: "kia",
|
||||
HyundaiAppID: "hyundai",
|
||||
|
||||
Stamps = map[string]*stampCollection{
|
||||
KiaAppID: {log: util.NewLogger("kia"), AppID: KiaAppID, Brand: "kia"},
|
||||
HyundaiAppID: {log: util.NewLogger("hyundai"), AppID: HyundaiAppID, Brand: "hyundai"},
|
||||
}
|
||||
)
|
||||
|
||||
func download(log *util.Logger, id, brand string) {
|
||||
var res StampCollection
|
||||
uri := fmt.Sprintf("https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/%s-%s.v2.json", brand, id)
|
||||
// New creates a new stamp
|
||||
func (c *stampCollection) Get() (string, error) {
|
||||
c.mu.Lock()
|
||||
defer c.mu.Unlock()
|
||||
|
||||
if err := client.GetJSON(uri, &res); err != nil {
|
||||
log.ERROR.Println(err)
|
||||
return
|
||||
length := float64(len(c.Stamps))
|
||||
position := float64(time.Since(c.Generated).Milliseconds()) / c.Frequency
|
||||
|
||||
// download
|
||||
if position >= 0.9*length {
|
||||
if time.Since(c.updated) > 15*time.Minute {
|
||||
c.log.TRACE.Printf("retry stamps download, last attempt: %v", c.updated)
|
||||
if err := c.download(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
|
||||
length = float64(len(c.Stamps))
|
||||
position = float64(time.Since(c.Generated).Milliseconds()) / c.Frequency
|
||||
}
|
||||
|
||||
mu.Lock()
|
||||
Stamps[id] = &res
|
||||
mu.Unlock()
|
||||
if position >= length {
|
||||
position = length - 1
|
||||
}
|
||||
|
||||
return c.Stamps[int64(position+5*rand.Float64())], nil
|
||||
}
|
||||
|
||||
// updateStamps updates stamps according to https://github.com/Hacksore/bluelinky/pull/144
|
||||
func updateStamps(log *util.Logger, id string) {
|
||||
if _, ok := updater[id]; ok {
|
||||
return
|
||||
func (c *stampCollection) download() error {
|
||||
c.updated = time.Now()
|
||||
|
||||
uri := fmt.Sprintf("https://raw.githubusercontent.com/neoPix/bluelinky-stamps/master/%s-%s.v2.json", c.Brand, c.AppID)
|
||||
|
||||
if err := client.GetJSON(uri, &c); err != nil {
|
||||
return fmt.Errorf("failed to download stamps: %w", err)
|
||||
}
|
||||
|
||||
updater[id] = struct{}{}
|
||||
download(log, id, brands[id])
|
||||
|
||||
go func() {
|
||||
for range time.NewTicker(24 * time.Hour).C {
|
||||
download(log, id, brands[id])
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// New creates a new stamp
|
||||
func (s StampsRegistry) New(id string) string {
|
||||
mu.Lock()
|
||||
defer mu.Unlock()
|
||||
|
||||
source := s[id]
|
||||
if source == nil {
|
||||
panic(id)
|
||||
}
|
||||
|
||||
position := float64(time.Since(source.Generated).Milliseconds()) / source.Frequency
|
||||
|
||||
return source.Stamps[int64(position+5*rand.Float64())]
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue