github.com/e154/smart-home@v0.17.2-0.20240311175135-e530a6e5cd45/plugins/updater/plugin.go (about)

     1  // This file is part of the Smart Home
     2  // Program complex distribution https://github.com/e154/smart-home
     3  // Copyright (C) 2016-2023, Filippov Alex
     4  //
     5  // This library is free software: you can redistribute it and/or
     6  // modify it under the terms of the GNU Lesser General Public
     7  // License as published by the Free Software Foundation; either
     8  // version 3 of the License, or (at your option) any later version.
     9  //
    10  // This library is distributed in the hope that it will be useful,
    11  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
    13  // Library General Public License for more details.
    14  //
    15  // You should have received a copy of the GNU Lesser General Public
    16  // License along with this library.  If not, see
    17  // <https://www.gnu.org/licenses/>.
    18  
    19  package updater
    20  
    21  import (
    22  	"context"
    23  	"embed"
    24  	"fmt"
    25  	"time"
    26  
    27  	"github.com/e154/smart-home/common"
    28  	"github.com/e154/smart-home/common/events"
    29  	"github.com/e154/smart-home/common/logger"
    30  	m "github.com/e154/smart-home/models"
    31  	"github.com/e154/smart-home/system/supervisor"
    32  )
    33  
    34  const (
    35  	name = "updater"
    36  	uri  = "https://api.github.com/repos/e154/smart-home/releases/latest"
    37  )
    38  
    39  var (
    40  	log = logger.MustGetLogger("plugins.updater")
    41  )
    42  
    43  var _ supervisor.Pluggable = (*plugin)(nil)
    44  
    45  //go:embed Readme.md
    46  //go:embed Readme.ru.md
    47  var F embed.FS
    48  
    49  func init() {
    50  	supervisor.RegisterPlugin(Name, New)
    51  }
    52  
    53  type plugin struct {
    54  	*supervisor.Plugin
    55  	ticker *time.Ticker
    56  }
    57  
    58  // New ...
    59  func New() supervisor.Pluggable {
    60  	p := &plugin{
    61  		Plugin: supervisor.NewPlugin(),
    62  	}
    63  	p.F = F
    64  	return p
    65  }
    66  
    67  // Load ...
    68  func (p *plugin) Load(ctx context.Context, service supervisor.Service) (err error) {
    69  	if err = p.Plugin.Load(ctx, service, p.ActorConstructor); err != nil {
    70  		return
    71  	}
    72  
    73  	if _, err = p.Service.Adaptors().Entity.GetById(context.Background(), common.EntityId(fmt.Sprintf("%s.%s", EntityUpdater, Name))); err != nil {
    74  		entity := &m.Entity{
    75  			Id:         common.EntityId(fmt.Sprintf("%s.%s", EntityUpdater, Name)),
    76  			PluginName: Name,
    77  			Attributes: NewAttr(),
    78  		}
    79  		err = p.Service.Adaptors().Entity.Add(context.Background(), entity)
    80  	}
    81  
    82  	_ = p.Service.EventBus().Subscribe("system/entities/+", p.eventHandler)
    83  
    84  	go func() {
    85  		const pause = 24
    86  		p.ticker = time.NewTicker(time.Hour * pause)
    87  
    88  		for range p.ticker.C {
    89  			p.Actors.Range(func(key, value any) bool {
    90  				actor, _ := value.(*Actor)
    91  				actor.check()
    92  				return true
    93  			})
    94  		}
    95  	}()
    96  
    97  	return
    98  }
    99  
   100  // Unload ...
   101  func (p *plugin) Unload(ctx context.Context) (err error) {
   102  	if p.ticker != nil {
   103  		p.ticker.Stop()
   104  	}
   105  
   106  	_ = p.Plugin.Unload(ctx)
   107  
   108  	_ = p.Service.EventBus().Unsubscribe("system/entities/+", p.eventHandler)
   109  	return
   110  }
   111  
   112  // ActorConstructor ...
   113  func (p *plugin) ActorConstructor(entity *m.Entity) (actor supervisor.PluginActor, err error) {
   114  	actor = NewActor(entity, p.Service)
   115  	return
   116  }
   117  
   118  // Name ...
   119  func (p *plugin) Name() string {
   120  	return name
   121  }
   122  
   123  // Type ...
   124  func (p *plugin) Type() supervisor.PluginType {
   125  	return supervisor.PluginBuiltIn
   126  }
   127  
   128  // Depends ...
   129  func (p *plugin) Depends() []string {
   130  	return nil
   131  }
   132  
   133  // Version ...
   134  func (p *plugin) Version() string {
   135  	return Version
   136  }
   137  
   138  func (p *plugin) eventHandler(_ string, msg interface{}) {
   139  
   140  	switch v := msg.(type) {
   141  	case events.EventCallEntityAction:
   142  		values, ok := p.Check(v)
   143  		if !ok {
   144  			return
   145  		}
   146  		for _, value := range values {
   147  			actor := value.(*Actor)
   148  			actor.check()
   149  		}
   150  	}
   151  }
   152  
   153  // Options ...
   154  func (p *plugin) Options() m.PluginOptions {
   155  	return m.PluginOptions{
   156  		ActorAttrs:   NewAttr(),
   157  		ActorActions: supervisor.ToEntityActionShort(NewActions()),
   158  		ActorStates:  supervisor.ToEntityStateShort(NewStates()),
   159  	}
   160  }