Any easy way to get cryptocurrency values in OH?
Thanks!
Yes
EDIT:
The above answer fits your question
Since you give no information what “easy” for you is and how much you are willing to invest.
You could use APIs like CoinMarketCap to get some data and parse it to openHAB items.
But you gave ZERO INFORMATION about your setup!
If you use for example HABPanel you could also create just HTML panels with data from Coinbase
Or like this click_me
Again no information provided!
While I agree that the question could have been more fully formed, I don’t think the sarcasm is necessary. This isn’t something that’s going to be in the docs, and there are no search results for “crypto currency” (though I didn’t look deeper than that).
You’re basically picking on the word “easy”, but if they had asked “has anyone tried getting cryptocurrency values into OH?”, the one-liner question would be a perfectly fine starting point for a discussion. Besides, you were able to provide pretty good options without needing more information.
There are definitely cases where posters need to provide more information in order to be properly helped (e.g. solving a problematic rule without providing the code), but I don’t think this is one of them. And I don’t think we should ever respond to these cases sarcastically. It just pushes people away.
Please note that this isn’t personal (I don’t think we’ve spoken before). I just think that sarcasm is one of the main problems with many communities/forums/comments on the web, and we’d all be better off with less of it.
I agree with you, I was in a conf-call when I posted so 1 of my 2 neurons was busy already
Let’s see if I can elaborate a little better…
Is there a simple method to get crypto values from coinmarketcap or similar APIs and have them as items in OH?
As of now I am doing it via a PowerShell script that writes data to a MQTT topic and then I have the items configured through the MQTT binding but I guess that there is to be a better way to get the values in OH.
Any suggestions?
Pls and thanks!
I obtain share prices from www.alphavantage.co using their free api and use this rule below to update the different items.
import java.util.List
val List<String> stocks = newArrayList("TW", "TCG", "SLA", "RMG", "BARC", "VOD") // Each stock symbol
rule "Get share prices"
when
Time cron "0 1/15 * ? * * *"
then
logInfo("org.openhab","Shares: Obtaining the latest prices.")
stocks.forEach[ stock, i |
val csv = sendHttpGetRequest("https://www.alphavantage.co/query?function=TIME_SERIES_INTRADAY&symbol=LON:"+stock+"&interval=15min&outputsize=compact&datatype=csv&apikey=MYAPIKEYGOESHERE").split("\n")
val firstLine = csv.get(2).split(",")
val price = firstLine.get(2).trim
sendCommand(stock+"_Current_Price", price)
]
logInfo("org.openhab","Shares: Updated completed.")
end
You are right, and I want to apologize for my sarcasm.
If you’re looking for an easy way to keep tabs on cryptocurrency values in OH, I’ve got a suggestion for you. Consider exploring a crypto wallet as a service. These wallets offer a user-friendly and efficient way to stay up-to-date with real-time cryptocurrency prices and market trends. Whether you’re an experienced crypto trader or just getting started, having a reliable source for the latest values can be incredibly valuable.
For instance, the MPC wallet as a service not only simplifies the process of monitoring your cryptocurrency portfolio but also comes with added security features to safeguard your digital assets.
Here’s my rule that runs every 12 minutes for the last few years.
items:
Group StockMarket
Number BTC_USD_JSON "BTC Price [%.2f]" (StockMarket, Group_HabPanel_Dashboard)
Number BTC_USD_Yesterday "BTC Price An Hour Ago [%.2f]" (StockMarket, Group_HabPanel_Dashboard)
Number ETH_USD_JSON "ETH Price [%.2f]" (StockMarket, Group_HabPanel_Dashboard)
Number ETH_USD_Yesterday "ETH Price An Hour Ago [%.2f]" (StockMarket, Group_HabPanel_Dashboard)
rule:
rule "Crypto Quote Lookup 24x7"
when
Time cron "0 0/12 * * * ?" // every 12 Minutes
then
if (systemStarted.state != ON && gInternet.state == ON && CryptoStart_tAlive === null && OH_Uptime_HumanReadable.state != NULL && OH_Uptime_HumanReadable.state !== null && OH_Uptime_HumanReadable.state != UNDEF) {
logInfo("tAlive","CryptoStart_tAlive is null --> CREATING Timer!")
CryptoStart_tAlive = createTimer(now().plusNanos(5000), [ |
var String BTCPullOK = 'Yes'
var String ETHPullOK = 'Yes'
var MailBinding = getThingStatusInfo("mail:smtp:4228b22a33")
BTCPullOK = 'No'
try {
var String results = executeCommandLine(Duration.ofSeconds(10), "/bin/bash", "/etc/openhab/scripts/BTC2.sh")
var String Temp = transform("JSONPATH", "$.['data']['priceUsd']", results.toString())
logInfo("CRYPTO","Attempt BTC Price prior to String::format " + Temp )
Temp = String::format("%.2f", Float.parseFloat(Temp))
logInfo("CRYPTO","Attempt BTC Price is $" + Temp)
BTC_USD_JSON.postUpdate(Float::parseFloat(String::format("%s",Temp)))
BTCPullOK = 'Yes'
} catch (Exception d) {
logError("CRYPTO","BTC Symbol - Error while processing JSON response via CURL. Exception is " + d.getMessage)
BTCPullOK = 'No'
}
ETHPullOK = 'No'
try {
var String results2 = executeCommandLine(Duration.ofSeconds(10), "/bin/bash", "/etc/openhab/scripts/ETH2.sh")
var String Temp2 = transform("JSONPATH", "$.['data']['priceUsd']", results2.toString())
logInfo("CRYPTO","Attempt ETH Price prior to String::format " + Temp2 )
Temp2 = String::format("%.2f", Float.parseFloat(Temp2))
logInfo("CRYPTO","Attempt ETH Price is $" + Temp2)
ETH_USD_JSON.postUpdate(Float::parseFloat(String::format("%s",Temp2)))
ETHPullOK = 'Yes'
} catch (Exception d) {
logError("CRYPTO","ETH Symbol - Error while processing JSON response via CURL. Exception is " + d.getMessage)
ETHPullOK = 'No'
}
if (gInternet.state == ON && BTCPullOK == 'No' && ETHPullOK == 'No') {
logInfo("tAlive","CryptoStart_tAlive ran out --> nulling timer.")
CryptoStart_tAlive = null
return;
}
if (BTCPullOK == 'Yes' && BTC_Speaking_Switch.state != ON && gInternet.state == ON && BTC_USD_JSON.state <= 15001.00 && currHour.state <= 6 && currHour.state >= 20) {
BTC_Speaking_Switch.postUpdate(ON)
logInfo("tAlive","CREATING Generic 81 Timer!")
createTimer(now().plusNanos(1000), [ |
var EchoThing = getThingStatusInfo("amazonechocontrol:account:account1")
if ((EchoThing !== null) && (EchoThing.getStatus().toString() == 'ONLINE' && gDnD_TTS_Bedroom_Guest.state != ON)) {
var String Message = '<speak>Wake up, Wake up, bitcoin value is below, fifteen thousand dollars.</speak>'
Echo_Bedroom_textToSpeechVolume.sendCommand('50')
Thread::sleep(1500)
Echo_Bedroom.sendCommand(Message)
Thread::sleep(3500)
Echo_Bedroom.sendCommand(Message)
Thread::sleep(3500)
Echo_Bedroom.sendCommand(Message)
Thread::sleep(3500)
}
])
Echo_LivingRoom_TTS.sendCommand(Message)
Thread::sleep(3000)
}
if (BTCPullOK == 'Yes' && BTC_Speaking_Switch.state != ON && gInternet.state == ON && BTC_USD_JSON.state <= 20001.00 && currHour.state <= 6 && currHour.state >= 20) {
BTC_Speaking_Switch.postUpdate(ON)
logInfo("tAlive","CREATING Generic 82 Timer!")
createTimer(now().plusNanos(1000), [ |
var EchoThing = getThingStatusInfo("amazonechocontrol:account:account1")
if ((EchoThing !== null) && (EchoThing.getStatus().toString() == 'ONLINE' && gDnD_TTS_Bedroom_Guest.state != ON)) {
var String Message2 = '<speak>Wake up, Wake up, bitcoin value is below, twenty thousand dollars.</speak>'
Echo_Bedroom_textToSpeechVolume.sendCommand('50')
Thread::sleep(1500)
Echo_Bedroom.sendCommand(Message2)
Thread::sleep(3500)
Echo_Bedroom.sendCommand(Message2)
Thread::sleep(3500)
Echo_Bedroom.sendCommand(Message2)
Thread::sleep(3500)
}
])
Echo_LivingRoom_TTS.sendCommand(Message2)
Thread::sleep(3000)
}
if (gInternet.state == ON && BTC_USD_JSON.state !== null && BTC_USD_JSON.state != NULL && BTC_USD_JSON.state != UNDEF) {
if (gInternet.state == ON && BTC_USD_Yesterday.state != NULL && BTC_USD_JSON.state != NULL) {
var Number BTC_USD_Diff_Up = (BTC_USD_JSON.state as Number) - (BTC_USD_Yesterday.state as Number)
var Number BTC_USD_Diff_Down = (BTC_USD_Yesterday.state as Number) - (BTC_USD_JSON.state as Number)
if (BTCPullOK == 'Yes' && BTC_USD_Diff_Up !== null && BTC_USD_Diff_Up > 499.00) {
if ((MailBinding !== null) && (MailBinding.getStatus().toString() == 'ONLINE' && gInternet.state == ON && gPort25.state == ON)) {
val mailActions = getActions("mail","mail:smtp:4228b22a33")
val SGmailActions = getActions("mail","mail:smtp:b46a3da64b")
var String subjectemailbtcup = "BTC Up $500"
var String bodyemailbtcup = "BTC value is UP at least $500 over a 12 minute period. BTC is at $" + BTC_USD_JSON.state + "."
val String subjectemailbtcupSMS = "BTC Up $500 at $" + BTC_USD_JSON.state + "."
var String bodyemailbtcupSMS = ''
mailActions.sendMail(JaygMail, subjectemailbtcup, bodyemailbtcup)
Thread::sleep(200)
SGmailActions.sendMail(JaySMS, subjectemailbtcupSMS, bodyemailbtcupSMS)
Thread::sleep(200)
SGmailActions.sendMail(ParkerSMS, subjectemailbtcupSMS, bodyemailbtcupSMS)
Thread::sleep(200)
logInfo("EMAIL",subjectemailbtcup)
}
var String Message5 = '<speak><prosody rate="fast">Excuse me, bitcoin value has increased by, five hundred dollars, in a 12 minute period.</prosody></speak>'
var EchoThingJay = getThingStatusInfo("amazonechocontrol:echo:account1:echojay")
if ((EchoThingJay !== null) && (EchoThingJay.getStatus().toString() == 'ONLINE')) {
Echo_Jay_TTS.sendCommand(Message5)
Thread::sleep(1500)
}
Echo_LivingRoom_TTS.sendCommand(Message5)
Thread::sleep(3000)
if (BTCPullOK == 'Yes' && Basement_Power.state == ON && Switch_Basement_Light.state == ON) {
var EchoThingBasement = getThingStatusInfo("amazonechocontrol:echo:account1:echobasement")
if ((EchoThingBasement !== null) && (EchoThingBasement.getStatus().toString() == 'ONLINE')) {
Echo_Basement_TTS.sendCommand(Message5)
Thread::sleep(1500)
}
}
BTC_USD_Yesterday.postUpdate(BTC_USD_JSON.state) // set current value
}
if (BTCPullOK == 'Yes' && BTC_USD_Diff_Down !== null && BTC_USD_Diff_Down > 4999.00) {
if ((MailBinding !== null) && (MailBinding.getStatus().toString() == 'ONLINE' && gInternet.state == ON && gPort25.state == ON)) {
val mailActions = getActions("mail","mail:smtp:4228b22a33")
val SGmailActions = getActions("mail","mail:smtp:b46a3da64b")
var String subjectemailbtcdown = "BTC Down $5,000"
var String bodyemailbtcdown = "BTC value is DOWN at least $5,000 over a 12 minute period. BTC is at $" + BTC_USD_JSON.state + "."
val String subjectemailbtdownSMS = "BTC Down $5,000 at $" + BTC_USD_JSON.state + "."
var String bodyemailbtcdownSMS = ''
mailActions.sendMail(JaygMail, subjectemailbtcdown, bodyemailbtcdown)
Thread::sleep(200)
SGmailActions.sendMail(JaySMS, subjectemailbtdownSMS, bodyemailbtcdownSMS)
Thread::sleep(200)
SGmailActions.sendMail(ParkerSMS, subjectemailbtdownSMS, bodyemailbtcdownSMS)
Thread::sleep(200)
logInfo("EMAIL",subjectemailbtcdown)
}
logInfo("tAlive","CREATING Generic 84 Timer!")
createTimer(now().plusNanos(1000), [ |
var EchoThing = getThingStatusInfo("amazonechocontrol:account:account1")
if ((EchoThing !== null) && (EchoThing.getStatus().toString() == 'ONLINE')) {
var String Message6 = '<speak>Wake up, Wake up, bitcoin value has decreased by, five thousand dollars, in a 12 minute period.</speak>'
Echo_Bedroom_textToSpeechVolume.sendCommand('50')
Thread::sleep(3000)
Echo_Bedroom_TTS.sendCommand(Message6)
Thread::sleep(3000)
Echo_Bedroom_TTS.sendCommand(Message6)
Thread::sleep(3000)
Echo_Bedroom_TTS.sendCommand(Message6)
}
])
Echo_LivingRoom_TTS.sendCommand(Message6)
Thread::sleep(3000)
if (BTCPullOK == 'Yes' && Basement_Power.state == ON && Switch_Basement_Light.state == ON) {
var EchoThing = getThingStatusInfo("amazonechocontrol:account:account1")
if ((EchoThing !== null) && (EchoThing.getStatus().toString() == 'ONLINE')) {
Echo_Basement_TTS.sendCommand(Message6)
Thread::sleep(1500)
}
}
BTC_USD_Yesterday.postUpdate(BTC_USD_JSON.state) // set current value
}
if (BTCPullOK == 'Yes' && BTC_USD_Diff_Down !== null && BTC_USD_Diff_Down > 2499.00) {
if ((MailBinding !== null) && (MailBinding.getStatus().toString() == 'ONLINE' && gInternet.state == ON && gPort25.state == ON)) {
val mailActions = getActions("mail","mail:smtp:4228b22a33")
val SGmailActions = getActions("mail","mail:smtp:b46a3da64b")
var String subjectemailbtcdown = "BTC Down $2,500"
var String bodyemailbtcdown = "BTC value is DOWN at least $2,500 over a 12 minute period. BTC is at $" + BTC_USD_JSON.state + "."
val String subjectemailbtdownSMS = "BTC Down $2,500 at $" + BTC_USD_JSON.state + "."
var String bodyemailbtcdownSMS = ''
mailActions.sendMail(JaygMail, subjectemailbtcdown, bodyemailbtcdown)
Thread::sleep(200)
SGmailActions.sendMail(JaySMS, subjectemailbtdownSMS, bodyemailbtcdownSMS)
Thread::sleep(200)
SGmailActions.sendMail(ParkerSMS, subjectemailbtdownSMS, bodyemailbtcdownSMS)
Thread::sleep(200)
logInfo("EMAIL",subjectemailbtcdown)
}
logInfo("tAlive","CREATING Generic 85 Timer!")
createTimer(now().plusNanos(1000), [ |
var EchoThing = getThingStatusInfo("amazonechocontrol:account:account1")
if ((EchoThing !== null) && (EchoThing.getStatus().toString() == 'ONLINE')) {
var String Message7 = '<speak><prosody rate="fast">Excuse me, bitcoin value has decreased by, twenty five hundred dollars, in a 12 minute period.</prosody></speak>'
Echo_Bedroom_textToSpeechVolume.sendCommand('50')
Thread::sleep(3000)
Echo_Bedroom_TTS.sendCommand(Message7)
Thread::sleep(3000)
Echo_Bedroom_TTS.sendCommand(Message7)
Thread::sleep(3000)
Echo_Bedroom_TTS.sendCommand(Message7)
}
])
Echo_LivingRoom_TTS.sendCommand(Message7)
Thread::sleep(3000)
if (BTCPullOK == 'Yes' && Basement_Power.state == ON && Switch_Basement_Light.state == ON) {
var EchoThing = getThingStatusInfo("amazonechocontrol:account:account1")
if ((EchoThing !== null) && (EchoThing.getStatus().toString() == 'ONLINE')) {
Echo_Basement_TTS.sendCommand(Message7)
Thread::sleep(1500)
}
}
BTC_USD_Yesterday.postUpdate(BTC_USD_JSON.state) // set current value
}
if (BTCPullOK == 'Yes' && BTC_USD_Diff_Down !== null && BTC_USD_Diff_Down > 499.00) {
if ((MailBinding !== null) && (MailBinding.getStatus().toString() == 'ONLINE' && gInternet.state == ON && gPort25.state == ON)) {
val mailActions = getActions("mail","mail:smtp:4228b22a33")
val SGmailActions = getActions("mail","mail:smtp:b46a3da64b")
var String subjectemailbtcdown = "BTC Down $500"
var String bodyemailbtcdown = "BTC value is DOWN at least $500 over a 12 minute period. BTC is at $" + BTC_USD_JSON.state + "."
val String subjectemailbtdownSMS = "BTC Down $500 at $" + BTC_USD_JSON.state + "."
var String bodyemailbtcdownSMS = ''
mailActions.sendMail(JaygMail, subjectemailbtcdown, bodyemailbtcdown)
Thread::sleep(200)
SGmailActions.sendMail(JaySMS, subjectemailbtdownSMS, bodyemailbtcdownSMS)
Thread::sleep(200)
SGmailActions.sendMail(ParkerSMS, subjectemailbtdownSMS, bodyemailbtcdownSMS)
Thread::sleep(200)
logInfo("EMAIL",subjectemailbtcdown)
}
var String Message8 = '<speak><prosody rate="fast">Excuse me, bitcoin value has decreased by, five hundred dollars, in a 12 minute period.</prosody></speak>'
var EchoThingJay = getThingStatusInfo("amazonechocontrol:echo:account1:echojay")
if ((EchoThingJay !== null) && (EchoThingJay.getStatus().toString() == 'ONLINE')) {
Echo_Jay_TTS.sendCommand(Message8)
Thread::sleep(1500)
}
Echo_LivingRoom_TTS.sendCommand(Message8)
Thread::sleep(3000)
if (BTCPullOK == 'Yes' && Basement_Power.state == ON && Switch_Basement_Light.state == ON) {
var EchoThingBasement = getThingStatusInfo("amazonechocontrol:echo:account1:echobasement")
if ((EchoThingBasement !== null) && (EchoThingBasement.getStatus().toString() == 'ONLINE')) {
Echo_Basement_TTS.sendCommand(Message8)
Thread::sleep(1500)
}
}
BTC_USD_Yesterday.postUpdate(BTC_USD_JSON.state) // set current value
}
} else {
logInfo("CRYPTO","The past 12 minute BTC value has NULL in them.")
BTCPullOK = 'No'
}
}
if (gInternet.state == ON && ETH_USD_JSON.state !== null && ETH_USD_JSON.state != NULL && ETH_USD_JSON.state != UNDEF) {
if (gInternet.state == ON && ETH_USD_Yesterday.state != NULL && ETH_USD_JSON.state != NULL) {
var Number ETH_USD_Diff_Up = (ETH_USD_JSON.state as Number) - (ETH_USD_Yesterday.state as Number)
var Number ETH_USD_Diff_Down = (ETH_USD_Yesterday.state as Number) - (ETH_USD_JSON.state as Number)
if (ETHPullOK == 'Yes' && ETH_USD_Diff_Up !== null && ETH_USD_Diff_Up > 199.00) {
if ((MailBinding !== null) && (MailBinding.getStatus().toString() == 'ONLINE' && gInternet.state == ON && gPort25.state == ON)) {
val mailActions = getActions("mail","mail:smtp:4228b22a33")
val SGmailActions = getActions("mail","mail:smtp:b46a3da64b")
var String subjectemailETHup = "ETH Up $200"
var String bodyemailETHup = "ETH value is UP at least $200 over a twelve minute period. ETH is at $" + ETH_USD_JSON.state + "."
val String subjectemailETHupSMS = "ETH Up $200 at $" + ETH_USD_JSON.state + "."
var String bodyemailETHupSMS = ''
mailActions.sendMail(JaygMail, subjectemailETHup, bodyemailETHup)
Thread::sleep(200)
SGmailActions.sendMail(JaySMS, subjectemailETHupSMS, bodyemailETHupSMS)
Thread::sleep(200)
SGmailActions.sendMail(JustinSMS, subjectemailETHupSMS, bodyemailETHupSMS)
logInfo("EMAIL",subjectemailETHup)
}
var String Message9 = '<speak><prosody rate="fast">Excuse me, Ethereum value has increased by, two hundred dollars, in a 12 minute period.</prosody></speak>'
var EchoThingJay = getThingStatusInfo("amazonechocontrol:echo:account1:echojay")
if ((EchoThingJay !== null) && (EchoThingJay.getStatus().toString() == 'ONLINE')) {
Echo_Jay_TTS.sendCommand(Message9)
Thread::sleep(3000)
}
Echo_LivingRoom_TTS.sendCommand(Message9)
Thread::sleep(3000)
if (systemStarted.state != ON && ETHPullOK == 'Yes' && Basement_Power.state == ON && Switch_Basement_Light.state == ON) {
var EchoThingBasement = getThingStatusInfo("amazonechocontrol:echo:account1:echobasement")
if ((EchoThingBasement !== null) && (EchoThingBasement.getStatus().toString() == 'ONLINE')) {
Echo_Basement_TTS.sendCommand(Message9)
Thread::sleep(3000)
}
}
ETH_USD_Yesterday.postUpdate(ETH_USD_JSON.state) // set current value
}
if (ETHPullOK == 'Yes' && ETH_USD_Diff_Down !== null && ETH_USD_Diff_Down > 199.00) {
if ((MailBinding !== null) && (MailBinding.getStatus().toString() == 'ONLINE' && gInternet.state == ON && gPort25.state == ON)) {
val mailActions = getActions("mail","mail:smtp:4228b22a33")
val SGmailActions = getActions("mail","mail:smtp:b46a3da64b")
var String subjectemailETHdown = "ETH Down $200"
var String bodyemailETHdown = "ETH value is DOWN at least $200 over a 12 minute period. ETH is at $" + ETH_USD_JSON.state + "."
val String subjectemailbtdownSMS = "ETH Down $200 at $" + ETH_USD_JSON.state + "."
var String bodyemailETHdownSMS = ''
mailActions.sendMail(JaygMail, subjectemailETHdown, bodyemailETHdown)
Thread::sleep(200)
SGmailActions.sendMail(JaySMS, subjectemailbtdownSMS, bodyemailETHdownSMS)
Thread::sleep(200)
SGmailActions.sendMail(JustinSMS, subjectemailbtdownSMS, bodyemailETHdownSMS)
logInfo("EMAIL",subjectemailETHdown)
}
var String Message10 = '<speak><prosody rate="fast">Excuse me, Ethereum value has decreased by, two hundred dollars, in a 12 minute period.</prosody></speak>'
var EchoThingJay = getThingStatusInfo("amazonechocontrol:echo:account1:echojay")
if ((EchoThingJay !== null) && (EchoThingJay.getStatus().toString() == 'ONLINE')) {
Echo_Jay_TTS.sendCommand(Message10)
Thread::sleep(3000)
}
Echo_LivingRoom_TTS.sendCommand(Message10)
Thread::sleep(3000)
if (systemStarted.state != ON && ETHPullOK == 'Yes' && Basement_Power.state == ON && Switch_Basement_Light.state == ON) {
var EchoThingBasement = getThingStatusInfo("amazonechocontrol:echo:account1:echobasement")
if ((EchoThingBasement !== null) && (EchoThingBasement.getStatus().toString() == 'ONLINE')) {
Echo_Basement_TTS.sendCommand(Message10)
Thread::sleep(3000)
}
}
ETH_USD_Yesterday.postUpdate(ETH_USD_JSON.state) // set current value
}
} else {
logInfo("CRYPTO","The past 12 minute ETH value has NULL in them.")
ETHPullOK = 'No'
}
}
logInfo("tAlive","CryptoStart_tAlive timer ran out --> nulling timer.")
CryptoStart_tAlive = null
])
}
end
btc2.sh script
#!/bin/bash
#https://docs.coincap.io/#f8869879-171f-4240-adfd-dd2947506adc
#
curl --location -s -k -H "Accept: application/json" 'api.coincap.io/v2/assets/bitcoin'
exit
exit
eth2.sh script
#!/bin/bash
#https://docs.coincap.io/#f8869879-171f-4240-adfd-dd2947506adc
#
curl --location -s -k -H "Accept: application/json" 'api.coincap.io/v2/assets/ethereum'
exit
exit
Best, Jay