Jump to content
  • Sign Up
Støtt hjemmeautomasjon.no!

Recommended Posts

Posted

Fra og med versjon 0.0.3.0 kan du scripte med data fra TibberSeer! Det gir flere muligheter for smartere strømstyring. :)

 

 

 

Litt historie

TibberSeer har alltid kunnet finne deg de N laveste timene med strømpriser, og brukt det som en trigger i et event. Hvis du f.eks. bare skal ha et eller annet på de 4 billigste timene, kan du bruke denne triggeren:

image.png

 

 

Det er et forholdsvis brutalt event, og hvis en eller flere av de N billigste timene kommer etter hverandre, så skrur man mye av og på igjen som over tid sliter på utstyret. Det har vi jo ikke noen glede av, så vi kan legge inn et event som skrur på hvis strømprisen er dyrere enn (24 - 4 - 1 = ) 19  billigste timer. 

 

Da får vi et på-event som dette:

image.png

 

og et av-event som dette:

image.png

 

 

 

Dette er jo fint og flott, men jeg vil gjerne at VVB skal gjøre seg ferdig med å varme vannet. Vi er 4 i husholdningen, det trenes en del så det brukes en del varmtvann i løpet av et døgn, og ingenting er verre enn å ikke ha varmtvann når man ønsker det.

 

Jeg har observert (dvs. sjekket statistikken) at at vår VVB etter dusjing om morgenen går på i ca. 2,5 timer før den går av. Av og til kortere og en sjelden gang lenger. I tillegg dusjes det om kvelden som gir igjen 2-2,5 timers oppvarming, eller boblebadet er i bruk som gir rundt 4 timers oppvarming.

 

Vi har da to perioder i døgnet som jeg er veldig interessert i å finne de billigste timene for, spesielt når strømprisene varierer en del... Hvordan gjør jeg det?

 

Nye scripting-funksjoner

TibberSeer har nå fått flere nye funksjoner som kan brukes med scripting. Det høres skummelt ut, men det er det ikke. :)

Dette er signaturen på de nye funksjonene:

 

Public Function GetPrices(Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As List(Of Double)
Public Function GetPricesAsDictionary(Optional ByVal startHour As Integer = 0, Optional ByVal hourCount As Integer = 0) As Dictionary(Of Integer, Double)

Public Function GetCheapestNhours(ByVal N As Integer, Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As Tuple(Of Date, Double)
Public Function GetCheapestNhoursTime(ByVal N As Integer, Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As Date
Public Function GetCheapestNhoursPrice(ByVal N As Integer, Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As Double

Public Function GetCheapestDhours(ByVal D As Double, Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As Tuple(Of Date, Double)
Public Function GetCheapestDhoursTime(ByVal D As Double, Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As Date
Public Function GetCheapestDhoursPrice(ByVal D As Double, Optional ByVal startHour As Integer = 0, Optional ByVal endHour As Integer = 0) As Double

Alle digger VB! :D

startHour og endHour er valgfrie variabler du kan bruke til å begrense søket ditt. Som standard vil de starte med å gi deg priser fra og med kl. 00:00 fra dagen i dag, og så mange timer som er tilgjengelige. 24 timer hvis funksjonen kjøres før kl 13 og 48 timer etter kl. 13.

 

GetPrices() og GetPricesAsDictionary() er to sider av samme sak. De gir hhv. en liste eller en dictionary over dagens og morgendagens strømpriser (hvis de finnes når funksjonen kjøres). De har litt forskjellig bruk og den varierer litt med hva du har tenkt å gjøre.

 

GetCheapestNhours() gir deg altså klokkeslett og gjennomsnittspris for de N billigste timene sammenhengende. Hvis du bruker GetCheapestNhours(3) så får du en Tuple med to verdier. Item1 er klokkeslett (og dato) for den timen som starter de tre sammenhengende timen, og Item2 er gjennomsnittsprisen for de 3 timene. GetCheapestNhoursTime() gir kun tidspunktet, og GetCheapestNhoursPrice() gir kun gjennomsnittsprisen.

 

GetCheapestDhours() er den samme som GetCheapestNhours() men med den forskjellen at den første kan ha desimaltall, mens den siste tar kun heltall. Hvorfor to stykker? Fordi desimaltall-versjonen krever bittelitt mer beregning (et par doble for-løkker for å iterere seg gjennom hvert minutt i et døgn eller to) isteden for heltall-versjonen som bruker LINQ (dvs spørringer). Desimaltallsversjonen kan selvfølgelig også ta heltall hvis du ønsker. Jeg skrev heltallsversjonen først, og beholder begge.

 

 

Eksempel

En normal hverdag er jeg i dusjen ganske nøyaktig kl. 07:00, og VVB vil begynne oppvarmingen omtrent da hvis man ikke styrer det. Dette er et dyrt tidspunkt å varme vann på, og det vil jeg gjøre noe med. Jeg vil altså ha de 2,5 billigste timene fra kl. 6-7 og til kl. 18. Dette gjør jeg i et script som skal kjøre kl. 06:00.

 

'Henter pris-info fra TibberSeer
Dim hours As Double = 2.5 'antall timer som sammenhengende skal ha lavest snittpris
Dim hourStart As Integer = Now.Hour 'Vi er ikke interessert i data som har vært.
Dim hourEnd As Integer = 18 '"Look ahead". 0 tilsier alle tilgjengelige data

Dim D As Tuple(Of Date, Double) = hs.PluginFunction("TibberSeer", "", "GetCheapestDhours", New Object() {hours, hourStart, hourEnd})

 

I variabelen D har jeg da D.Item1 som er klokkeslettet som har de billigste neste 2.5 timene, og D.Item2 inneholder snittprisen for disse 2.5 timene.

 

Dette kan jeg bruke til å lage et event som skrur på VVB på det ønskete tidspunktet:

 

'DeviceRef til VVB switch
Dim devRef As Integer = 3071

'Finner CAPI-kommando for "On" for VVB-devicen
Dim onCC As HomeSeerAPI.CAPI.CAPIControl = hs.CAPIGetSingleControl(devRef, True, "On", False, False)

'Lager et nytt event med "VVB på" kommando
eventRef = hs.NewEventGetRef("VVB På (pris-trigger)", "Automatisk (strømstyring)", String.Empty)
hs.EventSetTimeTrigger(eventRef, New Date(D.Item1.Year, D.Item1.Month, D.Item1.Day, D.Item1.Hour, D.Item1.Minute, 0))
hs.AddDeviceActionToEvent(eventRef, onCC)
hs.DeleteAfterTrigger_Set(eventRef)
hs.SaveEventsDevices()
hs.WriteLog("Tibber VVB", "Lagde nytt VVB på trigger-event")

 

I sin enkleste form kan da scriptet se slik ut. Lagre som TibberVVB.vb og kjør det hver dag kl. 06:00.

    Sub Main(ByVal input As Object)
        'Moskus 2022

        'DeviceRev til VVB switch
        Dim devRef As Integer = 3071

        'Henter pris-info fra TibberSeer
        Dim hours As Double = 2.5 'antall timer som sammenhengende skal ha lavest snittpris
        Dim hourStart As Integer = Now.Hour 'Vi er ikke interessert i data som har vært.
        Dim hourEnd As Integer = 18 '"Look ahead". 0 tilsier alle tilgjengelige data

        'Henter billigste timer og snittpris fra TibberSeer
        Dim D As Tuple(Of Date, Double) = hs.PluginFunction("TibberSeer", "", "GetCheapestDhours", New Object() {hours, hourStart, hourEnd})

        'Finner CAPI-kommando for "On" for VVB-devicen
        Dim onCC As HomeSeerAPI.CAPI.CAPIControl = hs.CAPIGetSingleControl(devRef, True, "On", False, False)

        'Lager et nytt event med "VVB på" kommando
        Dim eventRef As Integer = hs.NewEventGetRef("VVB På (pris-trigger)", "Automatisk (strømstyring)", String.Empty)
        hs.EventSetTimeTrigger(eventRef, New Date(D.Item1.Year, D.Item1.Month, D.Item1.Day, D.Item1.Hour, D.Item1.Minute, 0))
        hs.AddDeviceActionToEvent(eventRef, onCC)
        hs.DeleteAfterTrigger_Set(eventRef)
        hs.SaveEventsDevices()
        hs.WriteLog("Tibber VVB", "Lagde nytt VVB på trigger-event")
    End Sub

 

 

Avansert eksempel

Jeg sa jo at vi kjører VVB to ganger i døgnet. Samtidig er jeg interessert i å finne ut hvor mye penger man sparer på å f.eks. flytte strømforbruket fra kll. 7 til kl. 13 (hvis det er tidspunktet som er billigst). Et varsel på mobilen når funksjonen er kjørt er selvfølgelig nyttig, og en failsafe slik at vi får varmtvann selv om Tibber skulle være nede kan være greit for å sikre husfreden.

 

Et større, mer avansert script vil da kunne se slik ut:

 

    Sub Main(ByVal parm As Object)
        Dim devRef As Integer = 3071 'Device til VVB ON/OFF
        Dim vvb_kW As Double = 2.6 'kW

        'Henter pris-info fra TibberSeer
        Dim hours As Double = 2.5 'antall timer som sammenhengende skal ha lavest snittpris
        Dim hourStart As Integer = Now.Hour 'Vi er ikke interessert i data som har vært.
        Dim hourEnd As Integer = 18 '"Look ahead". 0 tilsier alle tilgjengelige data (dvs vi har 24 timer med data før ca. kl. 13 og 48 timer med data etter)

        Dim hourNormalStart As Integer = 7
        Dim hourNormalEnd As Integer = Math.Ceiling(hourNormalStart + hours)

        If Now.Hour > 16 Then 'Fra kl. 17:00 og utover
            hours = 4.5
            hourEnd = 24 + 7 'Kl. 07:00 i morgen
            hourNormalStart = 19
            hourNormalEnd = Math.Ceiling(hourNormalStart + hours)
        End If

        Dim D As Tuple(Of Date, Double) = hs.PluginFunction("TibberSeer", "", "GetCheapestDhours", New Object() {hours, hourStart, hourEnd})
        Dim startOn As Date = D.Item1

        If D.Item2 > 0 Then    'Tibber har data
            'Finner hva strømkostnaden hadde vært 
            Dim D_normalt As Tuple(Of Date, Double) = hs.PluginFunction("TibberSeer", "", "GetCheapestDhours", New Object() {hours, hourNormalStart, hourNormalEnd})


            'Beregner besparelse
            Dim pris_nå As Double = D.Item2 * vvb_kW / 100 * hours
            Dim pris_normalt As Double = D_normalt.Item2 * vvb_kW / 100 * hours
            Dim besparelse As Double = pris_normalt - pris_nå

            'Skriver til log og Pushover
            Dim msg As String = "Billigste " & hours & " deltimer starter " & D.Item1.ToString & " med snittpris: " & D.Item2 & " øre (normal besparelse: " & besparelse.ToString("f2") & " kr, eller " & (1 - pris_nå / pris_normalt).ToString("P1") & ")"
            hs.WriteLog("Tibber VVB", msg)
            hs.PluginFunction("Pushover 3P", "", "Pushscript", New Object() {"All Clients", msg, "VVB", "Low", "none", Nothing, Nothing, Nothing, Nothing})
            My.Computer.FileSystem.WriteAllText(hs.GetAppPath & "\Logs\VVB_" & devRef & ".txt", D.Item1.ToString & vbTab & D.Item2 & " øre" & vbTab & besparelse.ToString("f2") & " kr (" & (1 - pris_nå / pris_normalt).ToString("P1") & ")" & vbNewLine, True)

        Else     'Failsafe i tilfelle vi ikke har Tibber-data
            If Now.Hour < 16 Then
                startOn = Now.Date.AddHours(13).AddMinutes(5) 'Dvs kl. 13:05 i dag
            Else
                startOn = Now.Date.AddDays(1).AddHours(2) 'Dvs kl. 02:00 i morgen
            End If
            hs.WriteLog("Tibber VVB Warning", "Tibber-data ikke gyldig, VVB skrus på :" & startOn.ToString)
        End If



        'Sletter eksisterende event hvis det finnes, for da har det ikke kjørt som det skulle
        Dim eventRef As Integer = hs.GetEventRefByName("VVB På (pris-trigger)")
        If eventRef > 0 Then
            hs.DeleteEventByRef(eventRef)
            'hs.WriteLog("Tibber VVB", "Trigger På-event eksisterde, men det er nå slettet...")
        End If

        'Finner CAPI-kommando for "On" for VVB-devicen
        Dim onCC As HomeSeerAPI.CAPI.CAPIControl = hs.CAPIGetSingleControl(devRef, True, "On", False, False)

        'Lager et nytt event med "VVB på" kommando
        eventRef = hs.NewEventGetRef("VVB På (pris-trigger)", "Automatisk (strømstyring)", String.Empty)
        hs.EventSetTimeTrigger(eventRef, New Date(startOn.Year, startOn.Month, startOn.Day, startOn.Hour, startOn.Minute, 0))
        hs.AddDeviceActionToEvent(eventRef, onCC)
        hs.DeleteAfterTrigger_Set(eventRef)
        hs.SaveEventsDevices()
        hs.WriteLog("Tibber VVB", "Lagde nytt VVB på trigger-event")
    End Sub

... og det overlatas til lesaren sjølv at tolka innhaldet. Men spør hvis noe er uklart. ;)

 

Det er gøy å få beskjed om "Billigste 2,5 timer starter kl. 13:30 med en snittpris på 119,3 øre (normal besparelse 9,34 kr (89,7%)".

 

 

En siste sak:

Jeg har et event som slår av VVB hvis effekten har vært 0 over 10 minutter. Ellers må du finne en annen måte å å slå av VVB på, f.eks. 3 timer etter at den ble skrud på.

  • Like 9
  • 2 weeks later...
Posted

Sikkert eit dumt spørsmål for racere på VB...
Tester dette scriptet og kjører det klokka 06:00 hver morgen, "Dim hours As Double  (antall timer som sammenhengende skal ha lavest snittpris) er satt til 2,5 timer som standard i scriptet. 
De fleste ganger når dette blir kjørt klokka 06:00, blir resultatet at billigste 2,5 deltimer starter klokka 06:00 og da skjer det ingenting, VVB blir ikkje slått på.
Kjørte scriptet på nytt i dag klokka 07:55 og da blir resultatet at VVB starter klokka 15:29. 

Noe jeg gjør feil? 

 image.thumb.png.b0ac8dc61162a9b9c15607c985363858.png

 

Når ein ser på dagens strømpris, virker det logisk at "billigste 2,5 deltimer" blir satt til 06:00.

Jeg kunne ha kjørt scriptet klokka 07:00 (eller satt "billigste deltimer" høyere enn 2,5) og starttidspunktet på VVB ville nok ha blitt dyttet over kneika på strømprisen rundt 10:00 og over til ettermiddagen. 

Men det skal vel ikke være slik at VVB ikkje skal starte opp når starttidspunkt er det samme som tidspunkt for kjøring av script?

image.thumb.png.cc8eb1ea145277e76d0ffda79fe8975e.png

Posted

Prøvde meg på å endre tidspunkt på kjøring av script til klokka 05:58 i dag, men fikk da følgende:

image.thumb.png.3b3cd26b620d284b2b4e4e485ba760ba.png

 

 

image.thumb.png.472f9f64d2413b69601a69687e39f952.png

VVB tanken skulle da slåes på klokka 05:00 men det blir vanskelig i ettertid...

Hvordan unngå slike hendelser?
Takk. 

 

Posted
Olex skrev (På 29.6.2022 den 8.42):

De fleste ganger når dette blir kjørt klokka 06:00, blir resultatet at billigste 2,5 deltimer starter klokka 06:00 og da skjer det ingenting, VVB blir ikkje slått på.

Du kan kjøre det kl. 05:55, men da må du også endre dette:

Dim hourStart As Integer = Now.Hour

 

til dette:

Dim hourStart As Integer = Now.Hour + 1

 

:) 

  • Like 2
Posted

Hei!

Om eg skrur av VVB på grunn av effekttledd/Høgt snittbruk på slutten av en time, vil den då starte på nytt ved start av ny time, eller må eg starte den manuelt?

Posted
Join skrev (13 timer siden):

Om eg skrur av VVB på grunn av effekttledd/Høgt snittbruk på slutten av en time, vil den då starte på nytt ved start av ny time, eller må eg starte den manuelt?

Det kommer jo an på hvordan du har automatisert "på-skruingen".

 

Jeg er usikker på om jeg forstår spørsmålet. Kan den siste setningen i den øverste posten være svar på spørsmålet?

Posted
Moskus skrev (2 timer siden):

Det kommer jo an på hvordan du har automatisert "på-skruingen".

 

Jeg er usikker på om jeg forstår spørsmålet. Kan den siste setningen i den øverste posten være svar på spørsmålet?

Hei! :)

 

Takk for svar.

 

I øverste posten står det at scriptet vil slå på VVB, men at eg må slå den av manuelt.

 

Dvs, om den må skrues av for å holde effekttariff, må eg starte den sjølv.

 

Eg skal sjå etter muligheter for å starte VVB på ny ved starten av ny time, om scriptet har kjørt siste 3-4timer.

 

:)

Posted (edited)

Flott script og takk for at du deler. Endelig kan jeg velge hvilke timer som skal scannes, men sliter selvfølgelig litt. Gjør jeg noe galt eller sliter scriptet med overgangen ved midnatt?

 

Event som kjører script:

IF
This event is MANUALLY triggered
 
THEN
Run the script: TibberVVB.vb
                     and only allow one instance of the script to run at a time.

 

Script:
Sub Main(ByVal input As Object)
        'Moskus 2022

        'DeviceRev til VVB switch
        Dim devRef As Integer = 404

        'Henter pris-info fra TibberSeer
        Dim hours As Double = 2 'antall timer som sammenhengende skal ha lavest snittpris
        Dim hourStart As Integer = Now.Hour +1 'Vi er ikke interessert i data som har vært.
        Dim hourEnd As Integer = 8 '"Look ahead". 0 tilsier alle tilgjengelige data

        'Henter billigste timer og snittpris fra TibberSeer
        Dim D As Tuple(Of Date, Double) = hs.PluginFunction("TibberSeer", "", "GetCheapestDhours", New Object() {hours, hourStart, hourEnd})

        'Finner CAPI-kommando for "On" for VVB-devicen
        Dim onCC As HomeSeerAPI.CAPI.CAPIControl = hs.CAPIGetSingleControl(devRef, True, "On", False, False)

        'Lager et nytt event med "VVB på" kommando
        Dim eventRef As Integer = hs.NewEventGetRef("VVB På (pris-trigger)", "Automatisk (strømstyring)", String.Empty)
        hs.EventSetTimeTrigger(eventRef, New Date(D.Item1.Year, D.Item1.Month, D.Item1.Day, D.Item1.Hour, D.Item1.Minute, 0))
        hs.AddDeviceActionToEvent(eventRef, onCC)
        hs.DeleteAfterTrigger_Set(eventRef)
        hs.SaveEventsDevices()
        hs.WriteLog("Tibber VVB", "Lagde nytt VVB på trigger-event")
    End Sub

 

Jeg har kjørt scriptet i 22-23 tiden, men da får jeg følgende ukomplette event generert:

 

image.thumb.png.eb7456e81c19ff8c52d568bb0e5b5c72.png

 

 

Hvis jeg derimot endrer "Dim hourEnd" til 0, eller kjører script etter midnatt så funker det. Har ikke prøvd andre tider på døgnet enda.

 

Dim hourStart med "Now.Hour" eller "Now.Hour +1" utgjør ingen forskjell.

 

EDIT: Fant ut av det. Må jo skrive f.eks. "Dim hourEnd As Integer = 24 + 8" for å sjekke frem til kl 8 neste dag..

 

Edited by Essand
  • Like 1
  • 2 months later...
Posted
MrTiger skrev (13 timer siden):

Kanskje et dumt spørsmål, men hvor er scriptet?

Det er det som står lengre opp under eksempel. Kopier all koden og lim inn i f.eks. notepad, og lagre den som "ett_eller_annet_navn.vb". Dermed har du scriptet ditt.

Posted
ZoRaC skrev (På 11.9.2022 den 18.11):

Får man besparelsen utbetalt, eller hvordan fungerer det, @Moskus? 😂

 

Ser ut til at jeg får denne hver morgen, men at det fungerer som det skal når den kjører på ettermiddagen.

Jeg tror ikke jeg har skjønt 100% hvordan det fungerer, har du noe tips til hva årsaken kan være?

image.png.87574afd60db349e676c491641ae003a.png

  • 4 weeks later...
Posted
ZoRaC skrev (På 13.9.2022 den 15.16):

Jeg tror ikke jeg har skjønt 100% hvordan det fungerer, har du noe tips til hva årsaken kan være?

 


Har du noe forslag, @Moskus? :) 

Posted

Legg til disse

hs.WriteLog("Test","Pris_nå: " & pris_nå)
hs.WriteLog("Test","Pris_normalt: " & pris_normalt)
hs.WriteLog("Test","besparelse: " & besparelse)

 

Under denne linja:

 

Dim besparelse As Double = pris_normalt - pris_nå

... så ser vi hva loggen sier.

Posted
Moskus skrev (12 timer siden):

... så ser vi hva loggen sier.


 

Sitat
Oct-10 08:00:05   Test besparelse: 1.61792382137608E+307
Oct-10 08:00:05   Test Pris_normalt: 1.61792382137608E+307
Oct-10 08:00:05   Test Pris_nå: 1.539

 

Posted

Kan det ha noe med dette å gjøre?

https://learn.microsoft.com/en-us/dotnet/visual-basic/language-reference/data-types/double-data-type

  • Precision. When you work with floating-point numbers, remember that they do not always have a precise representation in memory. This could lead to unexpected results from certain operations, such as value comparison and the Mod operator. For more information, see Troubleshooting Data Types.

Posted

Det tviler jeg på, formlene er like.

Dim pris_nå As Double = D.Item2 * vvb_kW / 100 * hours
Dim pris_normalt As Double = D_normalt.Item2 * vvb_kW / 100 * hours

 

Så det betyr t D_normalt ikke finner noe fornuftig av en eller annen grunn.

 

Veldig snålt!

Posted
Moskus skrev (1 time siden):

Det tviler jeg på, formlene er like.

Dim pris_nå As Double = D.Item2 * vvb_kW / 100 * hours
Dim pris_normalt As Double = D_normalt.Item2 * vvb_kW / 100 * hours

 

Så det betyr t D_normalt ikke finner noe fornuftig av en eller annen grunn.

 

Veldig snålt!

 

Først av alt tusen takk for et flott plugin og script! :)  Har kjørt dette noen uker nå og fungerer glimrende.  Men sleit også med at jeg fikk noen rare verdier på "normalt", som foresaket lottogevinster i besparelse :P  Prøvde å endre litt her og der og fant til slutt ut av hvis jeg la på +1 på "hourNormalEnd", så fikk jeg riktig beregning av besparelsen. Uten at jeg helt forstår grunnen..

 

image.thumb.png.3ff466a94b61d7d0bc4081891fc312f5.png

  • Like 1
Posted
Random skrev (6 timer siden):

Prøvde å endre litt her og der og fant til slutt ut av hvis jeg la på +1 på "hourNormalEnd", så fikk jeg riktig beregning av besparelsen.

 +1 funket! :) 

 

Sitat

Billigste 3 deltimer starter 11/10/2022 01:00:00 med snittpris: 2.4 øre (normal besparelse: 0.94 kr, eller 81.3%)

 

  • 4 weeks later...
Posted

Hei

 

Er det noen som har laget ett script som slår av varmen i huset hvis det ser ut til at en kommer til å bruke mer enn valg effekt-trinn?

 

F.eks 10 min før kl er hel, så ser en at snittet denne timen er 10,5 kwT. Slår da av all oppvarming i huset for å så slå de som var på igjen.

 

Har vannbårenvarme og bruker SDJ-Stat til å kontrollere varmen. 

  • 6 months later...
Posted

Med disse scriptmulighetene, er det vanskelig å bare lage til et script som skriver "rangeringen" av timen innenfor et gitt tidsrom eller gjeldende dag? Hadde vært greit å kunne visualisere det eller å bruke direkte i andre scripts.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.