Gå til innhold
  • Bli medlem
Støtt hjemmeautomasjon.no!

Script for dimming av lys


HSv

Anbefalte innlegg

Jeg mener dette er min første post her - jeg har hatt mye hjelp av å lese her, og nå er det kanskje på tide jeg bidrar litt.

Jeg har kikket etter et script som gjør det jeg ønsker (...og ikke minst på den måten jeg ønsker:-) uten å finne det - og har derfor prøvd å skrive et selv.

Jeg har "hentet inspirasjon" fra noen av Moskus' scripts.

Input parametre:

   <deviceref>:<start>:<stop>:<time>

 

Litt opplagt igrunn - men uansett vil dette endre devicen fra start til stopp, og bruke (tilnærmet) tid på det. (På grunn av litt avrundinger, så kan det ta noen sekunder mer eller mindre enn det du oppgir)

For å ikke sende altfor mange kommandoer, så begrenser jeg meg per default til maks 4 kommandoer per sec (kan konfigureres)

 

Noen spesialverdier:

start = -1 - da leser jeg nåværende verdi, og dimmer til stoppverdi

start = -2 - da leser jeg nåværende verdi, og øker/minker denne med stoppverdien

 

Eksempler:

100:10:30:5 - skru dev 100 fra 10% til 30% (uavhengig av hva nåværende verdi er)- og bruke 5 sec på det

100:-1:30:5 - skru device fra nåværende verdi til 30% - og bruke 5 sec.

100:-2:-10:5 - endre device 100 med sluttverdien. Her er både positiv og negativ verdi tillatt - Om device 100 var på 35% før du startet scriptet, så vil den være på 25% etterpå. (og igjen - bruker  5 sec)

 

Dette er ikke veldig foolproof - det er helt sikkert mulig å legge inn verdier som kræsjer hele scriptet - men så lang så fungerer det som jeg vil.
Blant annet så tester det ikke om det finnes noe <deviceref>... (ikke ennå iallefall)

Jeg kjører HomeSeer på Linux - ikke testet ut på en Windows-serveer (Og jeg har strengt tatt ikke planer om å gjøre det heller...)

 

Jeg bruker det hovedsakelig til to ting: Styre utelyset mitt på en litt elegant måte, samt å skånsomt skru opp lyset på soverommet om morgenen.

 

Kommentarer er mer en velkommen. Endringsforslag og "bug-reports" likeså

 

Spoiler

' SmartDimmer.vb , v. 2.0
'   This script requires 4 parameters, separated by ':'
'    - Device Reference ID
'    - Start level (%)  0 - 100 [integer]
'                       (use -1 for current devicevalue)
'                       (use -2 to add end level to current value)
'    - End level (%)    0 - 100 [integer]
'    - Time (sec)       1 - 3600 [integer]
'                               HSv, Feb. 2019

Public Module GlobalVars
  Public Shared infoLog  As Boolean = True      ' Log whats happening...?
  Public Shared warnLog  As Boolean = True      ' Log warnings...? (you really should!)
  Public Shared debugLog As Boolean = False     ' Log a bit more...?
End Module

Public Sub Main(ByVal _params As Object)
  Dim showLoc     As Boolean = False    ' Add location to the devicename when
                                        ' writing to the log
  Dim Waittime    As Integer = 250      ' Default minimum loop time in millisec
                                        ' - i.e. 250 means 4 times per sec.
  Dim MaxTimespan As Integer = 3600     ' Max timespan is one hour - I guess this can be changed if you need to...
  Dim LogID       As String  = "SmartDimmer"


' ---------------------------------------------------
'  There should not be anything to change below here
' ---------------------------------------------------

  ' I guess reading the input parameters would eb a good idea...
  Dim deviceRef  As Integer = Integer.parse(_params.ToString.split(":")(0))
  Dim Startvalue As Integer = Integer.parse(_params.ToString.split(":")(1))
  Dim Stopvalue  As Integer = Integer.parse(_params.ToString.split(":")(2))
  Dim Timespan   As Integer = Integer.parse(_params.ToString.split(":")(3))

  ' Does the device exist at all...?
  If ( Not hs.DeviceExistsRef(deviceRef)) Then
    Logging(LogID, "warn", "Device " & deviceRef & " does not exist - Exiting!")
    Exit Sub
  End If

  ' If startvalue is set to -1, then use the current devicevalue as start.
  ' Do this also if start and endvalue are the same
  ' ( changing from 10 to 10 doesn't make sense, so therefore I assume you meant change from <current> to <new> )
  If ( (Startvalue = -1) OrElse (Startvalue = Stopvalue) ) Then
    Startvalue = hs.DeviceValue(deviceRef)
  ElseIf (Startvalue < -1) Then
    Startvalue = hs.DeviceValue(deviceRef)
    Stopvalue  = Startvalue + Stopvalue
  End If

  ' Read the name of the device, as it's more human readable in the log
  Dim deviceName As String
  If showLoc Then
    deviceName = hs.devicename(deviceRef)
  Else
    deviceName = hs.GetDeviceByRef(deviceRef).name(hs)
  End If

  ' Check if inputs are within limits
  If Startvalue < 0           Then Startvalue = 0
  If Startvalue > 100         Then Startvalue = 100
  If Stopvalue  < 0           Then Stopvalue  = 0
  If Stopvalue  > 100         Then Stopvalue  = 100
  If Timespan   < 1           Then Timespan   = 1
  If Timespan   > MaxTimespan Then Timespan   = MaxTimespan

  ' let the log know what we are up to...
  Logging(LogID, "info", "Device " & deviceName & " - from " & Startvalue & "% to " & Stopvalue & "% over " & Timespan & "sec")

  If Stopvalue <> Startvalue Then
    ' Calculate change per <Waittime> millisec.
    Dim DeltaValue As Integer = (Stopvalue - Startvalue) / (Timespan * (1000/Waittime))

    ' The minimum change is 1 (or -1) - If it is less I need to change it to 1, and calculate a new step-time
    ' I.e - If I want to change from 0 to 10 in 20 sec - I need to change by 1 every 2 sec.
    If Math.Abs(DeltaValue) < 1 Then
      If Stopvalue < Startvalue Then
        DeltaValue = -1
      Else
        DeltaValue = 1
      End If
      Waittime  = Math.Abs(TimeSpan / (Startvalue - Stopvalue) * 1000)
    End If
    Logging(LogID, "debug", "Device " & deviceName & " - Deltavalue= " & DeltaValue & " , Waittime= " & Waittime)

    ' Need to declare this so that I don't bail at the first iteration
    Dim Previouslevel As Integer = Startvalue

    For Each cc As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(deviceRef)
      For Newlevel As Integer = Startvalue To Stopvalue Step DeltaValue

        ' Check if there is an override - i.e. the device has been changed outside the script
        If ((hs.DeviceValue(deviceRef) = Previouslevel) OrElse (Previouslevel = Startvalue)) Then
          ' Set the correct dim level
          cc.ControlValue = Newlevel
          hs.CAPIControlHandler(cc)
          Logging(LogID, "debug", "Device " & deviceName & " : " & Previouslevel & " -> " & Newlevel)

          ' Wait the required amount of time
          System.Threading.Thread.Sleep(Waittime)
          Previouslevel = Newlevel
        Else
          ' Manual override - You openend the pod bay doors yourself :-/
          ' Write a warning and get the h... outta' here
          Logging(LogID, "warn", "Device " & deviceName & " - Manual override, bailed out at " & Previouslevel & "% -> " & hs.DeviceValue(deviceRef) & "%")
          Exit Sub
        End If
      Next

      ' In case the device end up with an incorrect value (d.t. increments only in integers),
      ' then I set the final value outside the loop.
      If (hs.DeviceValue(deviceRef) <> Stopvalue) Then
        Logging(LogID, "debug", "Device " & deviceName & " : " & Previouslevel & " -> " & Stopvalue & " (Final touch)")
        cc.ControlValue = Stopvalue
        hs.CAPIControlHandler(cc)
      End If

      ' Be nice and let the log know we are done :-)
      Logging(LogID, "info", "Device " & deviceName & " - done!")
      Exit Sub
    Next
  Else
    ' Nothing for me to do here
    ' This means that the device is already at the StopValue.
    Logging(LogID, "warn", "Device " & deviceName & " nothing to do!")
  End If

End Sub

' Routine for writing to the log
Sub Logging(ByVal LogID As String, ByVal msgType As String, ByVal msg As String)
  Dim msgComplete As String
  Dim writetolog As Boolean = False

  Select Case msgType
    Case  "info"
      If GlobalVars.infoLog Then
        msgComplete = "Info: " & msg
        writetolog = True
      End If

    Case  "debug"
      If GlobalVars.debugLog Then
        msgComplete = "Debug: " & msg
        writetolog = True
      End If

    Case  "warn"
      If GlobalVars.warnLog Then
        msgComplete = "Warning: " & msg
        writetolog = True
      End If

    Case Else
      msgComplete = "Msgtype '" & msgType & "' undefined"
      writetolog = True
  End Select

  If writetolog Then hs.Writelog (LogID, msgComplete)

End Sub

 

 

 

Endret av HSv
Versjon 2.0
  • Like 1
Lenke til kommentar
Del på andre sider

Jeg satt og kikket på det - ser at du legger inn som skjult tekst - ser mye penere ut.
Så da er spørsmålet - hvordan legger jeg koden inn i posten på en elegant måte...?

 

 

Det kan nok generere en del trafikk. Om du ikke endrer på det så vil det maks sende 4 kommandoer pr. sec.
Men om du endrer Waittime i scriptet til f.eks 1000, så vil den sende kun hvert sekund, og justere for det.

I.e. om du har Waittime på 250, og dimmer fra 0 til 16 på 4 sec, så sender den 4 ganger pr sec i step på 1%
Om du endrere Waitime til 1000, så vil den sende hvert sec, i step på 4%

Om du vil bruke det til gradvis å øke lyset på soverommet, så vil du kanskje bare øke med step på 1% hvert 30 sekund eller så, og da er det jo ikke mye trafikk - da sendes jo kommando bare hvert 30 sec ?

Endret av Håkon S.
Lenke til kommentar
Del på andre sider

4 timer siden, Moskus skrev:

Legg inn koden i posten din. Det er enklere å legge inn scripts med copy/paste enn å måtte kopiere en fil til riktig sted. :)

Nailed it! ?

  • Like 1
Lenke til kommentar
Del på andre sider

Dette ser jo ut til å kunne erstatte solskinnsuret mitt, men grunnen til at jeg ikke gjør det er:

Det lar seg ikke avbryte.

Si at du starter en lenger sekvens (0-100% på en halv time), men ombestemmer deg mitt i. Det hadde vært greit med en måte å gi et signal til loop'en om å avbryte.

 

Det er nok flere måter å gjøre det på, f.eks.

  • HS global variables
  • eller en egen exit-funksjon som gjør en sjekk
  • eller kanskje enklest: En sjekk om devicen du styrer har den verdien den skal ha fått fra scriptet "forrige runde", og hvis ikke, avbryt loop'en.
  • Like 1
Lenke til kommentar
Del på andre sider

56 minutter siden, Moskus skrev:

Det lar seg ikke avbryte.

Godt poeng - om solskinnsuret starter, og jeg står med en gang og skrur lyset på fullt med veggbryteren (eller forteller Alexa at jeg skal sove lenger...) så vil jeg jo at scriptet skal stoppe!
Ny versjon kommer om ikke lenge ?

Lenke til kommentar
Del på andre sider

  • 1 måned senere...

Mye av grunnet til at jeg kjøpte homeseer er dette scriptet. Men jeg bruker det til og styre lys i hønsehus og det skal IKKE stoppe. Ser at det hender det stopper opp.

 

Er det slik at om jeg fjerner det jeg klippet ut her så bare går det?

    ' Need to declare this so that I don't bail at the first iteration
    dim Previouslevel as integer = Startvalue

    for each cc as HomeSeerAPI.CAPIControl in hs.CAPIGetControl(deviceRef)
      for Newlevel as integer = Startvalue to Stopvalue step DeltaValue

        ' Check if there is an override - i.e. the device has been changed outside the script
        if ((hs.DeviceValue(deviceRef) = Previouslevel) orElse (Previouslevel = Startvalue)) then
          ' Set the correct dim level
          cc.ControlValue = Newlevel
          hs.CAPIControlHandler(cc)

          ' Wait the required amount of time
          System.Threading.Thread.Sleep(Waittime)
          Previouslevel = Newlevel
        else
          ' Manual override - You openend the pod bay doors yourself :-/
          if writeLog then hs.WriteLog("ChangeDimmer", deviceName & " - Manual override, bailed out at " & Previouslevel & "%")
          exit sub
        end if
      next

 

 

 

 

Lenke til kommentar
Del på andre sider

Så hyggelig å høre .

 

Men nei, da fjerner du altfor mye. 
Jeg skal se om jeg ikke får lagt ut en nyere versjon av scriptet i morgen, og da kan jeg vise deg hva som må tas ut for at det ikke skal stoppe.

Lenke til kommentar
Del på andre sider

Jeg har akkurat lagt ut en ny versjon i det første innlegget.

 

Og her er en "spesialversjon" som ikke lar seg avbryte. Det er ikke veldig grundig testet, men se om ikke dette gjør det du ønsker.

 

Spoiler

' SmartDimmer.vb , v. 2.0
'
' NOTE - No-Interrupt version!!!
'
'   This script requires 4 parameters, separated by ':'
'    - Device Reference ID
'    - Start level (%)  0 - 100 [integer]
'                       (use -1 for current devicevalue)
'                       (use -2 to add end level to current value)
'    - End level (%)    0 - 100 [integer]
'    - Time (sec)       1 - 3600 [integer]
'                               HSv, Feb. 2019

Public Module GlobalVars
  Public Shared infoLog  As Boolean = True      ' Log whats happening...?
  Public Shared warnLog  As Boolean = True      ' Log warnings...? (you really should!)
  Public Shared debugLog As Boolean = False     ' Log a bit more...?
End Module

Public Sub Main(ByVal _params As Object)
  Dim showLoc     As Boolean = False    ' Add location to the devicename when
                                        ' writing to the log
  Dim Waittime    As Integer = 250      ' Default minimum loop time in millisec
                                        ' - i.e. 250 means 4 times per sec.
  Dim MaxTimespan As Integer = 3600     ' Max timespan is one hour - I guess this can be changed if you need to...
  Dim LogID       As String  = "SmartDimmer"


' ---------------------------------------------------
'  There should not be anything to change below here
' ---------------------------------------------------

  ' I guess reading the input parameters would eb a good idea...
  Dim deviceRef  As Integer = Integer.parse(_params.ToString.split(":")(0))
  Dim Startvalue As Integer = Integer.parse(_params.ToString.split(":")(1))
  Dim Stopvalue  As Integer = Integer.parse(_params.ToString.split(":")(2))
  Dim Timespan   As Integer = Integer.parse(_params.ToString.split(":")(3))

  ' Does the device exist at all...?
  If ( Not hs.DeviceExistsRef(deviceRef)) Then
    Logging(LogID, "warn", "Device " & deviceRef & " does not exist - Exiting!")
    Exit Sub
  End If

  ' If startvalue is set to -1, then use the current devicevalue as start.
  ' Do this also if start and endvalue are the same
  ' ( changing from 10 to 10 doesn't make sense, so therefore I assume you meant change from <current> to <new> )
  If ( (Startvalue = -1) OrElse (Startvalue = Stopvalue) ) Then
    Startvalue = hs.DeviceValue(deviceRef)
  ElseIf (Startvalue < -1) Then
    Startvalue = hs.DeviceValue(deviceRef)
    Stopvalue  = Startvalue + Stopvalue
  End If

  ' Read the name of the device, as it's more human readable in the log
  Dim deviceName As String
  If showLoc Then
    deviceName = hs.devicename(deviceRef)
  Else
    deviceName = hs.GetDeviceByRef(deviceRef).name(hs)
  End If

 


  ' Check if inputs are within limits
  If Startvalue < 0           Then Startvalue = 0
  If Startvalue > 100         Then Startvalue = 100
  If Stopvalue  < 0           Then Stopvalue  = 0
  If Stopvalue  > 100         Then Stopvalue  = 100
  If Timespan   < 1           Then Timespan   = 1
  If Timespan   > MaxTimespan Then Timespan   = MaxTimespan

  ' let the log know what we are up to...
  Logging(LogID, "info", "Device " & deviceName & " - from " & Startvalue & "% to " & Stopvalue & "% over " & Timespan & "sec")

  If Stopvalue <> Startvalue Then
    ' Calculate change per <Waittime> millisec.
    Dim DeltaValue As Integer = (Stopvalue - Startvalue) / (Timespan * (1000/Waittime))

    ' The minimum change is 1 (or -1) - If it is less I need to change it to 1, and calculate a new step-time
    ' I.e - If I want to change from 0 to 10 in 20 sec - I need to change by 1 every 2 sec.
    If Math.Abs(DeltaValue) < 1 Then
      If Stopvalue < Startvalue Then
        DeltaValue = -1
      Else
        DeltaValue = 1
      End If
      Waittime  = Math.Abs(TimeSpan / (Startvalue - Stopvalue) * 1000)
    End If
    Logging(LogID, "debug", "Device " & deviceName & " - Deltavalue= " & DeltaValue & " , Waittime= " & Waittime)

    Dim Previouslevel As Integer = Startvalue

    For Each cc As HomeSeerAPI.CAPIControl In hs.CAPIGetControl(deviceRef)
      For Newlevel As Integer = Startvalue To Stopvalue Step DeltaValue

        ' Set the correct dim level
        cc.ControlValue = Newlevel
        hs.CAPIControlHandler(cc)
        Logging(LogID, "debug", "Device " & deviceName & " : " & Previouslevel & " -> " & Newlevel)

        ' Wait the required amount of time
        System.Threading.Thread.Sleep(Waittime)
        Previouslevel = Newlevel
      Next

      ' In case the device end up with an incorrect value (d.t. increments only in integers),
      ' then I set the final value outside the loop.
      If (hs.DeviceValue(deviceRef) <> Stopvalue) Then
        Logging(LogID, "debug", "Device " & deviceName & " : " & Previouslevel & " -> " & Stopvalue & " (Final touch)")
        cc.ControlValue = Stopvalue
        hs.CAPIControlHandler(cc)
      End If

      ' Be nice and let the log know we are done ?
      Logging(LogID, "info", "Device " & deviceName & " - done!")
      Exit Sub
    Next
  Else
    ' Nothing for me to do here
    ' This means that the device is already at the StopValue.
    Logging(LogID, "warn", "Device " & deviceName & " nothing to do!")
  End If

End Sub
 

' Routine for writing to the log
Sub Logging(ByVal LogID As String, ByVal msgType As String, ByVal msg As String)
  Dim msgComplete As String
  Dim writetolog As Boolean = False

  Select Case msgType
    Case  "info"
      If GlobalVars.infoLog Then
        msgComplete = "Info: " & msg
        writetolog = True
      End If

    Case  "debug"
      If GlobalVars.debugLog Then
        msgComplete = "Debug: " & msg
        writetolog = True
      End If

    Case  "warn"
      If GlobalVars.warnLog Then
        msgComplete = "Warning: " & msg
        writetolog = True
      End If

    Case Else
      msgComplete = "Msgtype '" & msgType & "' undefined"
      writetolog = True
  End Select

  If writetolog Then hs.Writelog (LogID, msgComplete)

End Sub

' That's all folks!

 

Lenke til kommentar
Del på andre sider

@HSv

 

Etter noen dager med testing kan jeg fortelle deg at dette funker utmerket til mitt bruk.

Nå gjør jo ikke jeg noe mere avasnsert enn:

 

Lys av: 50:-1:0:1800

Lys på 50:0:65:1800

 

Men disse hønen har nå værdens beste naturlige oppvåkning og natta modus.

 

Takk.

Lenke til kommentar
Del på andre sider

Kult at det fungerer også til en oppgave jeg absolutt ikke hadde forestilt meg ?

 

Av nysgjerrighet - kjører du scriptet på Linux eller Windows?

Endret av HSv
  • Like 1
Lenke til kommentar
Del på andre sider

 

Linux.

Current Date/Time: 3/26/2019 4:12:39 PM
HomeSeer Version: HS3 Standard Edition 3.0.0.500
Linux version: Linux HomeTrollerSELv3 3.16.0-031600-generic #201408031935 SMP Sun Aug 3 23:56:17 UTC 2014 i686 i686 i686 GNU/Linux System Uptime: 0 Days 1 Hour 24 Minutes 47 Seconds
IP Address: 192.168.10.103
Number of Devices: 58
Number of Events: 3
Available Threads: 199
HSTouch Enabled: True
Event Threads: 0
Event Trigger Eval Queue: 0
Event Trigger Priority Eval Queue: 0
Device Exec Queue: 0
HSTouch Event Queue: 0
Email Send Queue: 0

Enabled Plug-Ins
3.0.1.252: Z-Wave

 

 

Tidligere gjorde jeg jobben med OpenHab og ikea trådfri, men pærene til ikea vil ikke dimme skikkelig ned. Dvs 1% er reelt ca 40% så nå er det med Fibaro dimmer og glødepærer.

Lenke til kommentar
Del på andre sider

  • 1 år senere...

Spørsmål til bruk av scriptet, 

 

Jeg prøvde å lage et evt som kjørte SmartDimmer kommandoer til 6 devices, der de ble anropt i samme event, men såvidt jeg kunne se så ble det bare kjørt på en av lysene. Jeg kjører på Linux, Ubuntu 18.04 og dimmerene er Fibaro dimmere. Jeg prøvde både med og uten å sjekke av "Only allow single instance to be run at a time". Er det meningen at dette skal virke eller prøver jeg på noe som HS3 ikke er laget for å gjøre? 

 

IF <condition>

Then run script and command (parametre) 

Then run script and command (parametre)

Then run script and command (parametre)

Then run script and command (parametre) 

Then run script and command (parametre) 

 

 

 

Lenke til kommentar
Del på andre sider

Det burde fungere med flere instanser i samme event, uten at jeg har brukt det noe sted selv.
Avhengig av parametrene du bruker, så kan det jo bli litt trafikk over Z-Wave dette, så mulig det er det som er problemet...?

Har du sjekket hva loggen sier?

Lenke til kommentar
Del på andre sider

  • 3 måneder senere...
  • 2 uker senere...
  • 5 måneder senere...

Har du denne delen øverst i scriptet?

 

Public Module GlobalVars
  Public Shared infoLog  As Boolean = True      ' Log whats happening...?
  Public Shared warnLog  As Boolean = True      ' Log warnings...? (you really should!)
  Public Shared debugLog As Boolean = False     ' Log a bit more...?
End Module

 

Kjører du Linux?

Lenke til kommentar
Del på andre sider

Evt kan du endre den nederste funksjonen til dette:

 

' Routine for writing to the log
Sub Logging(ByVal LogID As String, ByVal msgType As String, ByVal msg As String)
  Dim infoLog  As Boolean = True      ' Log whats happening...?
  Dim warnLog  As Boolean = True      ' Log warnings...? (you really should!)
  Dim debugLog As Boolean = False     ' Log a bit more...?
  
  Dim msgComplete As String
  Dim writetolog As Boolean = False

  Select Case msgType
    Case  "info"
      If GlobalVars.infoLog Then
        msgComplete = "Info: " & msg
        writetolog = True
      End If

    Case  "debug"
      If GlobalVars.debugLog Then
        msgComplete = "Debug: " & msg
        writetolog = True
      End If

    Case  "warn"
      If GlobalVars.warnLog Then
        msgComplete = "Warning: " & msg
        writetolog = True
      End If

    Case Else
      msgComplete = "Msgtype '" & msgType & "' undefined"
      writetolog = True
  End Select

  If writetolog Then hs.Writelog (LogID, msgComplete)

End Sub

 

 

så slipper du å styre med Globale moduler. :) 

  • Like 1
Lenke til kommentar
Del på andre sider

Bli med i samtalen

Du kan publisere innhold nå og registrere deg senere. Hvis du har en konto, logg inn nå for å poste med kontoen din.

Gjest
Skriv svar til emnet...

×   Du har limt inn tekst med formatering.   Lim inn uten formatering i stedet

  Du kan kun bruke opp til 75 smilefjes.

×   Lenken din har blitt bygget inn på siden automatisk.   Vis som en ordinær lenke i stedet

×   Tidligere tekst har blitt gjenopprettet.   Tøm tekstverktøy

×   Du kan ikke lime inn bilder direkte. Last opp eller legg inn bilder fra URL.

×
×
  • Opprett ny...

Viktig informasjon

Vi har plassert informasjonskapsler/cookies på din enhet for å gjøre denne siden bedre. Du kan justere dine innstillinger for informasjonskapsler, ellers vil vi anta at dette er ok for deg.