Skip to content

Commit

Permalink
added new option for lineid to fix stops with multiple lines having t…
Browse files Browse the repository at this point in the history
…he wrong data
  • Loading branch information
tofuSCHNITZEL committed Nov 24, 2022
1 parent ff40afd commit 569d735
Show file tree
Hide file tree
Showing 4 changed files with 96 additions and 19 deletions.
16 changes: 11 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,31 @@ sensor:
platform: wienerlinien
firstnext: first
stops:
- '4429'
- '3230'
- 4429
- stop: 4429
line: 100
firstnext: next
- 3230
```
## Configuration variables
key | description
-- | --
**platform (Required)** | The platform name.
**stops (Required)** | RBL stop ID's
**firstnext (Optional)** | `first` or `next` departure.
**stops (Required)** | List of stopids or a stop with extended settings (see above)
**lineid (Optional)** | ID of a Wiener Linien transport line - some stops have more than one line so its always good to add the lineid to get the correct data
**firstnext (Optional)** | `first` or `next` departure. Default: `first` (can be defined at a specific stop as well to "overrule" the global setting)

## Sample overview

![Sample overview](overview.png)

## Notes

You can find out the Stop ID (rbl number) thanks to [Matthias Bendel](https://github.com/mabe-at) [https://till.mabe.at/rbl/](https://till.mabe.at/rbl/)
You can find out the Stop ID thanks to [Matthias Bendel](https://github.com/mabe-at) [https://till.mabe.at/rbl/](https://till.mabe.at/rbl/)
The Line ID you can get from the URL in your browser after selecting a Line on the site (https://till.mabe.at/rbl/?**line=301**) or in this csv:
[wienerlinien-ogd-linien.csv](https://www.wienerlinien.at/ogd_realtime/doku/ogd/wienerlinien-ogd-linien.csv)


This platform is using the [Wienerlinien API](http://www.wienerlinien.at) API to get the information.
Expand Down
2 changes: 1 addition & 1 deletion custom_components/wienerlinien/const.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
"""Constants"""
BASE_URL = "http://www.wienerlinien.at/ogd_realtime/monitor?rbl={}"
BASE_URL = "https://www.wienerlinien.at/ogd_realtime/monitor?stopid={}"

DEPARTURES = {
"first": {"key": 0, "name": "{} first departure"},
Expand Down
2 changes: 1 addition & 1 deletion custom_components/wienerlinien/manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"domain": "wienerlinien",
"name": "Wienerlinien",
"version": "1.2.0",
"version": "1.3.0",
"documentation": "https://github.com/tofuSCHNITZEL/home-assistant-wienerlinien",
"issue_tracker": "https://github.com/tofuSCHNITZEL/home-assistant-wienerlinien/issues",
"dependencies": [],
Expand Down
95 changes: 83 additions & 12 deletions custom_components/wienerlinien/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,49 +17,100 @@
from custom_components.wienerlinien.const import BASE_URL, DEPARTURES

CONF_STOPS = "stops"
CONF_STOP = "stop"
CONF_APIKEY = "apikey"
CONF_FIRST_NEXT = "firstnext"
CONF_LINEID = "line"
CONF_FIRST = "first"
CONF_NEXT = "next"

SCAN_INTERVAL = timedelta(seconds=30)

PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend(
{
vol.Optional(CONF_APIKEY): cv.string,
vol.Optional(CONF_STOPS, default=None): vol.All(cv.ensure_list, [cv.string]),
vol.Optional(CONF_FIRST_NEXT, default="first"): cv.string,
vol.Required(CONF_STOPS): vol.All(
cv.ensure_list,
[
{
vol.Required(CONF_STOP): vol.Coerce(int),
vol.Optional(CONF_LINEID): vol.Coerce(int),
vol.Optional(CONF_FIRST_NEXT, default="first"): vol.In({CONF_FIRST,CONF_NEXT}),
},
vol.Coerce(int)
]
),
vol.Optional(CONF_FIRST_NEXT, default="first"): vol.In({CONF_FIRST,CONF_NEXT}),
}
)


_LOGGER = logging.getLogger(__name__)

UNIQUE_MONITORS = set()

async def async_setup_platform(hass, config, add_devices_callback, discovery_info=None):
"""Setup."""
stops = config.get(CONF_STOPS)
firstnext = config.get(CONF_FIRST_NEXT)
globalfirstnext = config.get(CONF_FIRST_NEXT)
dev = []
for stopid in stops:
monitorid = 0
lineid = None

for stop in stops:
if type(stop) is int:
stopid = stop
firstnext = globalfirstnext
else:
stopid = stop[CONF_STOP]
lineid = stop.get(CONF_LINEID)
firstnext = stop[CONF_FIRST_NEXT]

api = WienerlinienAPI(async_create_clientsession(hass), hass.loop, stopid)
data = await api.get_json()
try:
name = data["data"]["monitors"][0]["locationStop"]["properties"]["title"]
monitors = data["data"]["monitors"]
except Exception:
raise PlatformNotReady()
dev.append(WienerlinienSensor(api, name, firstnext))

if len(monitors) == 0:
_LOGGER.error(f"Invalid stopid provided - there are no monitors for stopid {stopid}")
continue

if lineid:
for monitorCount, monitor in enumerate(monitors):
if monitor["lines"][0].get("lineId") == lineid:
monitorid = monitorCount

stopname = monitors[monitorid]["locationStop"]["properties"]["title"].strip()
linename = monitors[monitorid]["lines"][0]["name"].strip()
destination = monitors[monitorid]["lines"][0]["towards"].strip()
vehicle_type = monitors[monitorid]["lines"][0]["type"]

name = f"{stopname} {linename} -> {destination}"
monitorID = name+firstnext

if monitorID not in UNIQUE_MONITORS:
UNIQUE_MONITORS.add(monitorID)
dev.append(WienerlinienSensor(api, name, firstnext, monitorid, vehicle_type))
else:
_LOGGER.warn("Skipping already existing monitor")

add_devices_callback(dev, True)


class WienerlinienSensor(Entity):
"""WienerlinienSensor."""

def __init__(self, api, name, firstnext):
def __init__(self, api, name, firstnext, monitorid, vehicle_type):
"""Initialize."""
self.api = api
self.firstnext = firstnext
self.monitorid = monitorid
self.vehicle_type = vehicle_type
self._name = name
self._state = None
self.attributes = {}
self._attr_unique_id = f"{name}-{firstnext}".replace(" ", "-")

async def async_update(self):
"""Update data."""
Expand All @@ -76,7 +127,7 @@ async def async_update(self):
if data is None:
return
try:
line = data["monitors"][0]["lines"][0]
line = data["monitors"][self.monitorid]["lines"][0]
departure = line["departures"]["departure"][
DEPARTURES[self.firstnext]["key"]
]
Expand All @@ -92,7 +143,10 @@ async def async_update(self):
"platform": line["platform"],
"direction": line["direction"],
"name": line["name"],
"countdown": departure["departureTime"]["countdown"],
"stopid": self.api.my_stopid(),
"lineid": line["lineId"],
"barrierFree": line["barrierFree"],
"trafficjam": line["trafficjam"],
}
except Exception:
pass
Expand All @@ -112,8 +166,22 @@ def state(self):

@property
def icon(self):
"""Return icon."""
return "mdi:bus"
"""Return icon according to vehicle."""
match self.vehicle_type:
case "ptMetro":
return "mdi:subway"
case "ptTram":
return "mdi:tram"
case "ptTramWLB":
return "mdi:train-variant"
case "ptBusCity":
return "mdi:bus"
case "ptBusNight":
return "mdi:bus-clock"
case "ptTrainS":
return "mdi:train"
case _:
return "mdi:bus"

@property
def extra_state_attributes(self):
Expand Down Expand Up @@ -147,3 +215,6 @@ async def get_json(self):
pass

return value

def my_stopid(self):
return self.stopid

0 comments on commit 569d735

Please sign in to comment.